|
-
Nov 8th, 2008, 11:42 AM
#1
Drag & Drop in Windows Forms
C# version here.
I'm sure others have posted about this topic before but I'm sure another won't hurt. I'll post various examples of drag & drop within the same control, between controls and between applications.
If you're interested in performing drag & drop operations in WinForms then I suggest that you read this and this at least.
I'll start with moving items between two ListBoxes, which is relatively simple.
1. Create a new WinForms application project.
2. Add two ListBoxes to the form.
3. Add the following code:
Code:
Private Sub Form1_Load(ByVal sender As Object, _
ByVal e As EventArgs) Handles MyBase.Load
'Allow data to be dropped on both ListBoxes.
Me.ListBox1.AllowDrop = True
Me.ListBox2.AllowDrop = True
'Populate the ListBoxes.
Me.ListBox1.Items.AddRange(New String() {"List 1, Item 1", _
"List 1, Item 2", _
"List 1, Item 3", _
"List 1, Item 4", _
"List 1, Item 5"})
Me.ListBox2.Items.AddRange(New String() {"List 2, Item 1", _
"List 2, Item 2", _
"List 2, Item 3", _
"List 2, Item 4", _
"List 2, Item 5"})
End Sub
Private Sub ListBox_MouseDown(ByVal sender As Object, _
ByVal e As MouseEventArgs) Handles ListBox1.MouseDown, _
ListBox2.MouseDown
Dim source As ListBox = DirectCast(sender, ListBox)
For index As Integer = 0 To source.Items.Count - 1
'Test whether the mouse location is within an item
If source.GetItemRectangle(index).Contains(e.Location) Then
'The mouse was depressed on an item so allow a move operation.
source.DoDragDrop(source, DragDropEffects.Move)
Exit For
End If
Next
End Sub
Private Sub ListBox_DragEnter(ByVal sender As Object, _
ByVal e As DragEventArgs) Handles ListBox1.DragEnter, _
ListBox2.DragEnter
Dim source As ListBox = DirectCast(sender, ListBox)
If e.Data.GetDataPresent("System.Windows.Forms.ListBox", False) AndAlso _
e.Data.GetData("System.Windows.Forms.ListBox", False) IsNot source Then
'The data being dragged is a ListBox but not the one that was just entered.
e.Effect = DragDropEffects.Move
End If
End Sub
Private Sub ListBox_DragDrop(ByVal sender As Object, _
ByVal e As DragEventArgs) Handles ListBox1.DragDrop, _
ListBox2.DragDrop
Dim source As ListBox = DirectCast(sender, ListBox)
If e.Data.GetDataPresent("System.Windows.Forms.ListBox", False) Then
'Get the ListBox that the data was dragged from.
Dim data As ListBox = DirectCast(e.Data.GetData("System.Windows.Forms.ListBox", _
False), _
ListBox)
'Make sure we aren't trying to drag from and drop to the same control.
If data IsNot source Then
'Get the item that was dragged.
Dim item As Object = data.SelectedItem
'Remove the item from its original location.
data.Items.Remove(item)
'Get the current mouse location relative to the control being dropped on.
Dim location As Point = source.PointToClient(New Point(e.X, e.Y))
Dim dropIndex As Integer = -1
'Find the item over which the mouse was released.
For index As Integer = 0 To source.Items.Count - 1
If source.GetItemRectangle(index).Contains(location) Then
dropIndex = index
Exit For
End If
Next
If dropIndex = -1 Then
'The mouse was not released over an item so add the new item to the end.
source.Items.Add(item)
Else
'Insert the new item above the item it was dropped on.
source.Items.Insert(dropIndex, item)
End If
End If
End If
End Sub
4. Run the project and start dragging and dropping.
I'll refine this example and add more over time. If there's anything you specifically want to see then post a request and I'll see if I can get to it.
As requested in post #34, I have reworked the above example to allow multiple items to be dragged and dropped.
vb.net Code:
Private Sub Form1_Load(ByVal sender As Object, _ ByVal e As EventArgs) Handles MyBase.Load 'Allow data to be dropped on both ListBoxes. Me.ListBox1.AllowDrop = True Me.ListBox2.AllowDrop = True 'All multiple selections. Me.ListBox1.SelectionMode = SelectionMode.MultiExtended Me.ListBox2.SelectionMode = SelectionMode.MultiExtended 'Populate the ListBoxes. Me.ListBox1.Items.AddRange(New String() {"List 1, Item 1", _ "List 1, Item 2", _ "List 1, Item 3", _ "List 1, Item 4", _ "List 1, Item 5"}) Me.ListBox2.Items.AddRange(New String() {"List 2, Item 1", _ "List 2, Item 2", _ "List 2, Item 3", _ "List 2, Item 4", _ "List 2, Item 5"}) End Sub Private Sub ListBox_MouseDown(ByVal sender As Object, _ ByVal e As MouseEventArgs) Handles ListBox1.MouseDown, _ ListBox2.MouseDown Dim source As ListBox = DirectCast(sender, ListBox) For index As Integer = 0 To source.Items.Count - 1 'Test whether the mouse location is within an item If source.GetItemRectangle(index).Contains(e.Location) Then 'The mouse was depressed on an item so allow a move operation. source.DoDragDrop(source, DragDropEffects.Move) Exit For End If Next End Sub Private Sub ListBox_DragEnter(ByVal sender As Object, _ ByVal e As DragEventArgs) Handles ListBox1.DragEnter, _ ListBox2.DragEnter Dim source As ListBox = DirectCast(sender, ListBox) If e.Data.GetDataPresent("System.Windows.Forms.ListBox", False) AndAlso _ e.Data.GetData("System.Windows.Forms.ListBox", False) IsNot source Then 'The data being dragged is a ListBox but not the one that was just entered. e.Effect = DragDropEffects.Move End If End Sub Private Sub ListBox_DragDrop(ByVal sender As Object, _ ByVal e As DragEventArgs) Handles ListBox1.DragDrop, _ ListBox2.DragDrop Dim source As ListBox = DirectCast(sender, ListBox) If e.Data.GetDataPresent("System.Windows.Forms.ListBox", False) Then 'Get the ListBox that the data was dragged from. Dim data As ListBox = DirectCast(e.Data.GetData("System.Windows.Forms.ListBox", _ False), _ ListBox) 'Make sure we aren't trying to drag from and drop to the same control. If data IsNot source Then 'Get the items that were dragged. Dim items As Object() = data.SelectedItems.Cast(Of Object).ToArray() 'Remove the items from their original location. For Each item In items data.Items.Remove(item) Next 'Get the current mouse location relative to the control being dropped on. Dim location As Point = source.PointToClient(New Point(e.X, e.Y)) Dim dropIndex As Integer = -1 'Find the item over which the mouse was released. For index As Integer = 0 To source.Items.Count - 1 If source.GetItemRectangle(index).Contains(location) Then dropIndex = index Exit For End If Next If dropIndex = -1 Then 'The mouse was not released over an item so add the new items to the end. source.Items.AddRange(items) Else 'Insert the new items above the item they were dropped on. For Each item In items source.Items.Insert(dropIndex, item) dropIndex += 1 Next End If End If End If End Sub
Last edited by jmcilhinney; Jul 5th, 2015 at 03:06 AM.
Reason: Added multi-item example.
Posting Permissions
- You may not post new threads
- You may not post replies
- You may not post attachments
- You may not edit your posts
-
Forum Rules
|
Click Here to Expand Forum to Full Width
|