Adding drag and drop functionality to an app is no rocket science. All it takes is setting some properties and handling some events. But browsing MSDN and Google to memorize exactly which properties and events you easily drown in all the info. Due to several reasons: there are quite a few events you don’t need (yet); most examples treat several totally different subjects which makes it hard to quickly distill the drag and drop stuff; and not all member names are that logical at first sight. Enough reason for a little summary.
What do I want to do : Drag some info from one windows control and drop that on another. As an example I’ll drag a label and drop it on a listbox to add the caption to the items. The control where the drag is started is the originator, the control which is dropped upon the target.
1. Start the drag operation in the originator. This is done by invoking the DoDragDrop method, a member of the Control base class. The average user expects to start a drag by clicking the mouse button, so a good place to fire of the method is the MouseDown event. The DoDragDrop method takes two parameters, the first one is an object which can contain any data you wish to drop on the target. The second parameter is an enumeration providing some info on the intent of the originator.
private void label_MyMouseDown(object sender, MouseEventArgs e)
DoDragDrop((sender as Label).Text, DragDropEffects.Link);
Now when the user holds down the mouse and moves it a little the drag operation starts. The cursor will change providing visual feedback.
The TreeView and the ListView control have an ItemDrag event, which fires when the user starts dragging an individual node or item. These are not in the DragDrop category but in the Action category. But when handling those events you invoke DoDragDrop the same way.
2. Select potential drop targets by setting their AllowDrop property to true.
3. In the drop target determine whether it will accept a drop. This is done in the DragEnter event. The code can inspect the originator’s intent by examining the AllowedEffect property. This enumeration has a bitflag, so it can combine several AllowedEffect‘s. The code can also check if data of a certain desired type is available by inspecting the Data property. Here the listbox checks on the Link effect and checks for the presence of string data.
private void listBox_MyDragEnter(object sender, DragEventArgs e)
if ((e.AllowedEffect & DragDropEffects.Link) != 0
e.Effect = DragDropEffects.Link;
By setting the Effect property the target tells it will accept a drop. The value of the Effect property determines what the cursor looks like when it enters the target. Targets which don’t have the AllowDrop property set or refuse to accept a drop will display a “no access” cursor.
4. Accept the drop and handle the data. When the user release the mouse and the target has expressed it will accept a drop the DragDrop event fires. This is passed the same DragEventArgs as the DragEnter event. Here the listbox actually extracts the string from the Data property, by invoking GetData instead of GetDataPresent, and adds it to its items.
private void listBox_MyDragDrop(object sender, DragEventArgs e)
(sender as ListBox).Items.Add(e.Data.GetData(typeof (string)));
That’s all. Note that all eventhandler snippets are not bound to a specific control, they all take the sender parameter to find their target. There are many more possibilities and gadgets concerning drag and drop. But this is all you need for the basic functionality to work.