
Description.
I've had a couple inquiries on how to do drag and drop in .NET again, so I've put together a simple app for dragging text from a TreeView to a TreeView and a TreeView to a ListBox.
Basically there are three events you need to handle when dragging from one item to another. In the case of TreeViews and ListViews, you need to handle the ItemDrag, DragEnter, and DragDrop events. In the case of other components such as listboxes ItemDrag is replaced by the MouseDown event. Also, all drop targets must have the AllowDrop property set to true. In the ItemDrag event you call the DoDragDrop routine as shown below:
Listing 1.
Private Sub treeView1_ItemDrag(sender As Object, e As System.Windows.Forms.ItemDragEventArgs)
Dim strItem As String = e.Item.ToString()
' Start the Drag Operation
DoDragDrop(strItem, DragDropEffects.Copy Or DragDropEffects.Move)
End Sub 'treeView1_ItemDrag
In the case above, we are dragging a string, however, you can drag bitmaps and metafiles as well by replacing the first parameter of DoDragDrop.
In order to maintain the "Drag" look, you need to handle the DragEnter event in both the source and the drop destination. The DragEnter event is shown below:
Listing 2.
Private Sub treeView2_DragEnter(sender As Object, e As System.Windows.Forms.DragEventArgs)
' Determine if we are dragging something, if we are, set the effect
If e.Data.GetDataPresent(DataFormats.Text) Then
e.Effect = DragDropEffects.Copy
Else
e.Effect = DragDropEffects.None
End If
End Sub 'treeView2_DragEnter
Now we need to handle the actual drop in the DragDrop event. In this example we actually determine where in the tree to drop the text using the position passed in from the DragEvent Arguement:
Listing 3.
Private Sub treeView2_DragDrop(sender As Object, e As System.Windows.Forms.DragEventArgs)
' Get the Data from the DragEventArguement
Dim dummy As String = "hello"
Dim s As String = CStr(e.Data.GetData(dummy.GetType()))
' Parse out the type information
s = s.Substring((s.IndexOf(":") + 1)).Trim()
Position.X = e.X
Position.Y = e.Y
' Convert from Form Coordinates to treeView Client coordinates
Position = treeView2.PointToClient(Position)
' Find the node at this position
Dim DropNode As TreeNode = Me.treeView2.GetNodeAt(Position)
' if the node exists, insert a new node with the dropped string
' into the second tree
If Not (DropNode Is Nothing) Then
Dim DragNode As New TreeNode(s)
treeView2.Nodes.Insert(DropNode.Index + 1, DragNode)
End If
End Sub 'treeView2_DragDrop
The ListBox handles drops the same way. The DragEnter Event for the listbox is set up to handle the DropEffects and the DragDrop event handler handles dropping the text:
Listing 4..
Private Sub listBox1_DragEnter(sender As Object, e As System.Windows.Forms.DragEventArgs)
' Handle the Drag effect when the listbox is entered
If e.Data.GetDataPresent(DataFormats.Text) Then
e.Effect = DragDropEffects.Copy
Else
e.Effect = DragDropEffects.None
End If
End Sub 'listBox1_DragEnter
Private Sub listBox1_DragDrop(sender As Object, e As System.Windows.Forms.DragEventArgs)
Dim dummy As String = "hello"
' Get the string from the data that was dragged
Dim s As String = CStr(e.Data.GetData(dummy.GetType()))
s = s.Substring((s.IndexOf(":") + 1)).Trim()
Position.X = e.X
Position.Y = e.Y
Position = listBox1.PointToClient(Position)
' Drop the string in the listbox
listBox1.Items.Add(s)
End Sub 'listBox1_DragDrop