In the process of finding a solution for this question, a new question has appeared.

WinForms controls for working with Drag'n'Drop in .NET have several typical events and the DoDragDrop method.

But there are several problems associated with them. If we activate DoDragDrop on the DoDragDrop event, then until the drag process is complete, our program window does not receive mouse events, but receives events associated with the drag and drop procedure. While everything seems to be logical, but if after the dragging of the object is activated, the mouse does not move, the procedure does not end immediately, but with an indefinite timeout, and at this time mouse events are not transmitted to our window, which actually caused the problem described in the question above.

For TreeView and ListView it turned out there is a solution out of the box - the ItemDrag event, but for other controls that could potentially become a source for Drag'n'Drop, there is no such solution.

So far only one solution has occurred:

  1. On the MouseDown event MouseDown raise the flag about the possible start of dragging and memorize the potential dragging object in the private fields of the form.

  2. On the MouseMove check the flag and status of the mouse buttons, and if the specified conditions are met, call the DoDragDrop method to the parameters of which to transfer the previously saved object as data for dragging. After that, reset the flag.

But for some reason it seems to me that this is a crutch, because depending on what and where we are going to drag, the code will differ and it will have to be duplicated for each form that requires such functionality.

Actually the question is, do I understand correctly that the drag and drop process is performed in the context of the operating system, rather than individual programs, in order to enable dragging and dropping objects between programs? If the assumption is correct, then is there a solution to bypass the listed problems more flexibly, without building bicycles of crutches? If my assumption is not true - then I would like to see in the answer how it actually works.

The question is addressed more likely to a WinAPI expert, but I would like to get a solution in the context of C #. In principle, for me, any solution that can be adapted for .NET is suitable, if it is better than what has already been stated.

    2 answers 2

    I will reason logically: You do not have too many controls that can take in a dragged object. I am sure that there are 1-3 of them on the form.

    So why not see how ItemDrag implemented in TreeView and ListView (good, the resources easily google on request "treeview source code" ) and not implement the ItemDrag event you need in the necessary controls by inheritance and subsequent expansion of capabilities?

    • The code will most likely be practically identical. (I mean the ItemDrag code for all heirs of the original classes)
    • Your program code will not be cluttered with unnecessary flags and methods. Everything will still be readable, as if these methods were out of the box there :)
    • In addition to the controls that can receive the received object, there are a bunch of other controllers on the form, for example sliders, which should react when the drag object is over them. Writing your DragDrop is not a problem, the problem is that some components of this mechanism affect too many controls. Obviously, this is all realizable in a general way through messages, but the trouble is that in c # the message manager is too deeply buried. - Alexander Muksimov
    • It was the first thought to look, only this is all in the native code, and the source code is available only for the referencesource.microsoft.com/#System.Windows.Forms/winforms/… shell. I thought about inheritance, but so far I am more inclined to the universal decorator, although I have not tried it in the code yet, there is no time yet. - rdorn
    • And the problem is, in general, not with the reception of the drag and drop, but with the start of dragging, "if, after activating dragging, the mouse does not move, the procedure does not end immediately, but with an indefinite timeout." - rdorn
    • @Alexander Muksimov does not need to rewrite DrugNDrop, it works fine, except for the bug with a delay in the completion of dragging if the mouse is stationary. - rdorn
    • one
      Thank you, you have come up with an interesting idea, I will try to accomplish your goal in detail, after the completion of the competition. - rdorn

    I would wrap controls in which you need to use Drag'n'Drop in the following shell:

    • Describe the field in which the object is located. Regarding this object, to produce a refresh if it is replaced by another.
    • Describe the method GetInnerType () - the definition of the type of object that can take control.
    • Well, describe about the controls with the MouseDown and MouseUp shells, with checking the IsDragging and DragContainer fields - where the current object is located.
    • Actually, on MouseUp, determine the type of the object relative to the DragContainer and verify with the GetInnerType object which accepts this object, well, to accept or not to accept the object inside.

    While such thoughts. Wrapping control ..

    • Thanks for participating, but please reread the question more carefully, the problem is quite different. In general, the technology works as it should out of the box, but there is one annoying bug that should be beautifully bypassed. - rdorn