Performing Drag-and-Drop Operations
Mike Gunderloy
Lark Group, Inc.
February 2002
Summary: Managing drag-and-drop in Microsoft Visual Basic .NET. (9 printed pages)
Objectives
- Understand drag-and-drop in Windows Forms
- Use Microsoft Visual Basic® .NET code to perform drag-and-drop operations
Assumptions
The following should be true for you to get the most out of this document:
- You are familiar with Visual Basic programming
- You understand the basic concept of drag-and-drop
- You have access to Visual Basic .NET
Contents
Drag-and-Drop
Practice Implementing Drag-and-Drop
Summary
Drag-and-Drop
Drag-and-drop is one of the fundamental metaphors underlying the Microsoft® Windows® family of operating systems. Users understand that some items can be moved around by holding the mouse down on them, and that they'll get appropriate visual feedback when they're over a spot where the item can be dropped. They expect to be able to move data and images from one spot to another this way. Visual Basic .NET makes it easy to implement drag-and-drop in your own applications. You can control all aspects of the process, including which controls allow dragging, what data they make available to drag, and where it can be dropped. You can implement this both within a single application and between applications. In this document, you'll learn how to manage drag-and-drop in Visual Basic .NET.
Note If you worked with OLE drag-and-drop in Visual Basic 6.0, you'll find that drag-and-drop in Microsoft .NET is very similar. But a number of terms and names have changed, so read the details carefully.
Beginning a Drag-and-Drop Operation
To begin a drag-and-drop operation, you call the DoDragDrop method of a Windows Forms control. The DoDragDrop method is implemented on the System.Windows.Forms.Control class, which means that it is available on all controls within the Windows Forms namespace.
The DoDragDrop method takes two arguments: the data to be dragged, and the drag operations that this control allows. You can call the DoDragDrop method at any time, although most frequently you'll want to use the MouseDown event as a way to trigger dragging when the user expects it. For example:
Private Sub txtDrag_MouseDown(ByVal sender As Object, _
ByVal e As System.Windows.Forms.MouseEventArgs)_
Handles txtDrag.MouseDown
txtDrag.DoDragDrop(txtDrag.Text, _
DragDropEffects.Copy Or DragDropEffects.Move)
End Sub
In this particular case, the code starts a drag operation whenever the user depresses the primary mouse button on the txt1 control. The data to be dragged is the text contained in the control, and the control allows both copy and move operations in drag-and-drop.
**Tip **The data to be dragged should be an instance of the String, Bitmap, or MetaFile class, or an object that implements the ISerializable or IDataObject interfaces.
The second argument to the DoDragDrop method is a combination of members from the DragDropEffects enumeration, indicating which target operations are valid for this data. Table 1 shows the members of this enumeration.
Table 1. DragDropEffects enumeration members
Member | Explanation |
---|---|
All | The data is copied, removed from the drag source, and scrolled in the target. |
Copy | The data is copied to the target. |
Link | The data is linked to the target. |
Move | The data is moved to the target. |
None | The target does not accept the data. |
Scroll | Scrolling is about to start or currently occurring in the target. |
Accepting Data From a Drag Operation
Any control can accept data from a drag-and-drop operation in progress. To designate a control as a drop zone, you must do three things:
- Set the AllowDrop property of the control to True.
- Handle the DragEnter property of the control.
- Handle the DragDrop property of the control.
The DragEnter event occurs when a drag-and-drop operation is in progress (that is, some control has called the DoDragDrop method) and the cursor enters the control. This event passes an argument of the System.Windows.Forms.DragEventArgs class. You should set the Effect property of this argument to a value from Table 1 to indicate the action that will be taken if the operation is completed on this control. The system will use this value to pick the appropriate drop cursor to display. For example:
Private Sub txtDrop_DragEnter(ByVal sender As Object, _
ByVal e As System.Windows.Forms.DragEventArgs) _
Handles txtDrop.DragEnter
If (e.Data.GetDataPresent(DataFormats.Text)) Then
If (e.KeyState And CtrlMask) = CtrlMask Then
e.Effect = DragDropEffects.Copy
Else
e.Effect = DragDropEffects.Move
End If
End If
End Sub
In this particular case, the code examines the KeyState property of the DragEventArgs argument to determine whether the Ctrl key is depressed as part of the drag operation. If it is, the control accepts this potential drop as a copy; if not, it accepts the drop as a move.
The DragEnter event provides visual feedback to the user that a drop is allowed on this particular control. If the user actually releases the mouse button on this control, then the DragDrop event is triggered. In this event, you should handle the actual mechanics of processing the dropped data. For example, this procedure inserts the dropped data into the target control:
Private Sub txtDrop_DragDrop(ByVal sender As Object, _
ByVal e As System.Windows.Forms.DragEventArgs) _
Handles txtDrop.DragDrop
txtDrop.Text = e.Data.GetData(DataFormats.Text)
End Sub
Other Drag-and-Drop Events
There are two other events the can be triggered on a target control as part of a drag-and-drop operation: DragOver and DragLeave.
The DragOver event happens as the cursor continues to move within the same control (similar to the MouseMove event):
Private Sub txtDrop_DragOver(ByVal sender As Object, _
ByVal e As System.Windows.Forms.DragEventArgs) _
Handles txtDrop.DragOver
…
End Sub
The DragLeave event happens when the cursor moves out of a control that was a potential drop target:
Private Sub txtDrop_DragLeave(ByVal sender As Object, _
ByVal e As System.EventArgs) _
Handles txtDrop.DragLeave
…
End Sub
Note that in the DragLeave event you do not have access to the DragEventArgs object. This event is useful for "cleaning up" any changes you made to the drop target when a drop doesn't happen. For example, you might highlight a target control during the DragEnter event and remove the highlight during the DragLeave event.
Drag-and-Drop Between Applications
You don't have to take any special steps to allow drag-and-drop between applications. Once you've started a drag-and-drop operation with the DoDragDrop method, the user can drag the data to any drop target within your application or in any other application. Only two conditions must be satisfied for an inter-application drag-and-drop operation to succeed:
- The drop target must allow at least one of the drag effects that were specified during the DoDragDrop method call.
- The drop target must accept the data in the format that the drag control provided.
Practice Implementing Drag-and-Drop
In the following example, you will implement drag-and-drop between controls in a simple Windows Forms component. You'll drag data within the application, and then drag the data from your application to another Windows application.
To create a drag-and-drop test project
Open Visual Studio .NET and choose New Project from the Start Page.
Select Visual Basic Project from the tree view on the left side of the screen.
Select Windows Application as the project template.
Set the name of the application to DragDrop and click OK to create the project.
Highlight the form called Form1.vb in the Solution Explorer window and rename it to frmDragDrop.vb.
Create the form shown in Figure 1 by adding the appropriate controls and setting the properties of those controls, as outlined in Table 2.
Table 2: Controls for frmDragDrop.vb
Control Type Property Value TextBox Name txt1 Text (blank) TextBox Name txt2 Text (blank) TextBox Name txt3 Text (blank) TextBox Name txt4 Text (blank) ListBox Name lboTarget AllowDrop True Figure 1. The drag-and-drop test form
Add Code to Implement Drag-and-Drop
Now you're ready to write code to perform drag-and-drop operations within this form. You'll write code to generate random values in the four text boxes, and then implement drag-and-drop from the text boxes to the list box. The list box code will complete the drag as a copy if the Ctrl key is pressed while the value is being dragged, otherwise it will create the drag as a move.
On the View menu, click Code and enter this code before the Windows Form Designer-generated code:
Const CtrlMask = 8
Private SourceControl As TextBox
Now enter this code after the Windows Form Designer-generated code:
Private Sub Form1_Load(ByVal sender As System.Object, _
ByVal e As System.EventArgs) Handles MyBase.Load
Randomize()
txt1.Text = Int(Rnd(1) * 10) + 1
txt2.Text = Int(Rnd(1) * 10) + 1
txt3.Text = Int(Rnd(1) * 10) + 1
txt4.Text = Int(Rnd(1) * 10) + 1
End Sub
Private Sub txt1_MouseDown(ByVal sender As Object, _
ByVal e As System.Windows.Forms.MouseEventArgs) _
Handles txt1.MouseDown
If Len(txt1.Text) > 0 Then
SourceControl = txt1
txt1.DoDragDrop(txt1.Text, _
DragDropEffects.Copy Or DragDropEffects.Move)
End If
End Sub
Private Sub txt2_MouseDown(ByVal sender As Object, _
ByVal e As System.Windows.Forms.MouseEventArgs) _
Handles txt2.MouseDown
If Len(txt2.Text) > 0 Then
SourceControl = txt2
txt2.DoDragDrop(txt2.Text, _
DragDropEffects.Copy Or DragDropEffects.Move)
End If
End Sub
Private Sub txt3_MouseDown(ByVal sender As Object, _
ByVal e As System.Windows.Forms.MouseEventArgs) _
Handles txt3.MouseDown
If Len(txt3.Text) > 0 Then
SourceControl = txt3
txt3.DoDragDrop(txt3.Text, _
DragDropEffects.Copy Or DragDropEffects.Move)
End If
End Sub
Private Sub txt4_MouseDown(ByVal sender As Object, _
ByVal e As System.Windows.Forms.MouseEventArgs) _
Handles txt4.MouseDown
If Len(txt4.Text) > 0 Then
SourceControl = txt4
txt4.DoDragDrop(txt4.Text, _
DragDropEffects.Copy Or DragDropEffects.Move)
End If
End Sub
Private Sub lboTarget_DragEnter( _
ByVal sender As System.Object, _
ByVal e As System.Windows.Forms.DragEventArgs) _
Handles lboTarget.DragEnter
If (e.Data.GetDataPresent(DataFormats.Text)) Then
If (e.KeyState And CtrlMask) = CtrlMask Then
e.Effect = DragDropEffects.Copy
Else
e.Effect = DragDropEffects.Move
End If
End If
End Sub
Private Sub lboTarget_DragDrop( _
ByVal sender As System.Object, _
ByVal e As System.Windows.Forms.DragEventArgs) _
Handles lboTarget.DragDrop
lboTarget.Items.Add(e.Data.GetData(DataFormats.Text))
If (e.KeyState And CtrlMask) <> CtrlMask Then
SourceControl.Clear()
End If
SourceControl = Nothing
End Sub
Here's what you'll find in this code:
- The code in the Form Load event uses random numbers to put some data in the four text boxes.
- Each text box checks in its MouseDown event to see whether there is any data in the text box. If so, it calls the DoDragDrop method to begin a drag-and-drop operation, and sets a reference to itself in the module-level SourceControl.
- The DragEnter event of the list box checks the KeyState property to determine whether the Ctrl key is pressed. If so, it displays the copy-drop cursor; otherwise, it displays the move-drop cursor.
- The DragDrop event of the list box takes the data from the drag and adds it to the list box. If the Ctrl key is pressed and held, it also clears the control that was the source of the data.
Try It Out
To see the drag-and-drop in action, follow these steps:
- Press F5 to start the project.
- Put the cursor in the first text box control, click and hold the mouse button, and start to move the mouse. You'll see the "no drop" symbol to indicate that you're dragging but are not yet over a drop target.
- Drag the cursor to the list box. The cursor will change to the move-drop symbol.
- Release the mouse button. The value from the first text box will be added to the list box, and the text box will be cleared.
- Put the cursor in the second text box control, hold down the Ctrl key, hold down the mouse button, and start to move the mouse. You'll see the "no drop" symbol to indicate that you're dragging but are not yet over a drop target.
- Drag the cursor to the list box. The cursor will change to the copy-drop symbol.
- Release the mouse button. The value from the second text box will be added to the list box, but the text box will not be cleared.
- Launch WordPad from the Start menu by clicking Programs, clicking Accessories, and then clicking WordPad. Arrange your screen so you can see both the frmDragDrop form and WordPad.
- Put the cursor in the third text box control, hold down the mouse button, and start to move the mouse. You'll see the "no drop" symbol to indicate that you're dragging but are not yet over a drop target.
- Drag the cursor to the list box. The cursor will change to the copy-drop symbol. Note that WordPad does not implement move-drop, so that you'll get a copy-drop even though you're not holding down the Ctrl key.
- Release the mouse button. The value from the third text box will be added to WordPad, but the text box will not be cleared.
Summary
Because all controls in the Windows Forms universe are ultimately descended from the System.Windows.Forms.Control class, the implementation of drag-and-drop is uniform throughout these controls. This makes writing drag-and-drop code in Visual Basic .NET very easy. On the drag side of the equation, you need only call the DoDragDrop method when the appropriate event (usually MouseDown) occurs. On the drop side, you need to set the AllowDrop property to True, then handle the DragEnter and DragDrop events. With a little practice, you should be able to write drag-and-drop code any time you require this functionality.
About the Author
Mike Gunderloy writes about software and raises chickens in eastern Washington state. He's the co-author of Access 2002 Developer's Handbook and author of SQL Server Developer's Guide to OLAP with Analysis Services, both from Sybex. He's been writing code for Microsoft products since the prehistoric pre-Windows era, and has no intention of stopping any time soon.
About Informant Communications Group
Informant Communications Group, Inc. (www.informant.com) is a diversified media company focused on the information technology sector. Specializing in software development publications, conferences, catalog publishing and Web sites, ICG was founded in 1990. With offices in the United States and the United Kingdom, ICG has served as a respected media and marketing content integrator, satisfying the burgeoning appetite of IT professionals for quality technical information.
Copyright © 2002 Informant Communications Group and Microsoft Corporation
Technical editing: PDSA, Inc. or KNG Consulting, Inc.