Drag and Drop Revisited




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 void treeView1_ItemDrag(object sender, System.Windows.Forms.ItemDragEventArgs e)
{
string strItem = e.Item.ToString();
// Start the Drag Operation
DoDragDrop(strItem, DragDropEffects.Copy | DragDropEffects.Move);
}

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 void treeView2_DragEnter(object sender, System.Windows.Forms.DragEventArgs e)
{
// Determine if we are dragging something, if we are, set the effect
if (e.Data.GetDataPresent(DataFormats.Text))
e.Effect = DragDropEffects.Copy;
else
e.Effect = DragDropEffects.None;
}

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 void treeView2_DragDrop(object sender, System.Windows.Forms.DragEventArgs e)
{
// Get the Data from the DragEventArguement
string dummy = "hello";
string s = (string)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
TreeNode DropNode = this.treeView2.GetNodeAt(Position);
// if the node exists, insert a new node with the dropped string
// into the second tree
if (DropNode != null)
{
TreeNode DragNode =
new TreeNode(s);
treeView2.Nodes.Insert(DropNode.Index+1, DragNode);
}
}

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 void listBox1_DragEnter(object sender, System.Windows.Forms.DragEventArgs e)
{
// Handle the Drag effect when the listbox is entered
if (e.Data.GetDataPresent(DataFormats.Text))
e.Effect = DragDropEffects.Copy;
else
e.Effect = DragDropEffects.None;
}
private void listBox1_DragDrop(object sender,
System.Windows.Forms.DragEventArgs e)
{
string dummy = "hello";
// Get the string from the data that was dragged
string s = (string)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);
}


Similar Articles