Results 1 to 38 of 38

Thread: Drag & Drop in Windows Forms

Threaded View

  1. #1

    Thread Starter
    Super Moderator jmcilhinney's Avatar
    Join Date
    May 2005
    Location
    Sydney, Australia
    Posts
    111,221

    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:
    1. Private Sub Form1_Load(ByVal sender As Object, _
    2.                    ByVal e As EventArgs) Handles MyBase.Load
    3.     'Allow data to be dropped on both ListBoxes.
    4.     Me.ListBox1.AllowDrop = True
    5.     Me.ListBox2.AllowDrop = True
    6.  
    7.     'All multiple selections.
    8.     Me.ListBox1.SelectionMode = SelectionMode.MultiExtended
    9.     Me.ListBox2.SelectionMode = SelectionMode.MultiExtended
    10.  
    11.     'Populate the ListBoxes.
    12.     Me.ListBox1.Items.AddRange(New String() {"List 1, Item 1", _
    13.                                              "List 1, Item 2", _
    14.                                              "List 1, Item 3", _
    15.                                              "List 1, Item 4", _
    16.                                              "List 1, Item 5"})
    17.     Me.ListBox2.Items.AddRange(New String() {"List 2, Item 1", _
    18.                                              "List 2, Item 2", _
    19.                                              "List 2, Item 3", _
    20.                                              "List 2, Item 4", _
    21.                                              "List 2, Item 5"})
    22. End Sub
    23.  
    24. Private Sub ListBox_MouseDown(ByVal sender As Object, _
    25.                               ByVal e As MouseEventArgs) Handles ListBox1.MouseDown, _
    26.                                                                  ListBox2.MouseDown
    27.     Dim source As ListBox = DirectCast(sender, ListBox)
    28.  
    29.     For index As Integer = 0 To source.Items.Count - 1
    30.         'Test whether the mouse location is within an item
    31.         If source.GetItemRectangle(index).Contains(e.Location) Then
    32.             'The mouse was depressed on an item so allow a move operation.
    33.             source.DoDragDrop(source, DragDropEffects.Move)
    34.  
    35.             Exit For
    36.         End If
    37.     Next
    38. End Sub
    39.  
    40. Private Sub ListBox_DragEnter(ByVal sender As Object, _
    41.                               ByVal e As DragEventArgs) Handles ListBox1.DragEnter, _
    42.                                                                 ListBox2.DragEnter
    43.     Dim source As ListBox = DirectCast(sender, ListBox)
    44.  
    45.     If e.Data.GetDataPresent("System.Windows.Forms.ListBox", False) AndAlso _
    46.        e.Data.GetData("System.Windows.Forms.ListBox", False) IsNot source Then
    47.         'The data being dragged is a ListBox but not the one that was just entered.
    48.         e.Effect = DragDropEffects.Move
    49.     End If
    50. End Sub
    51.  
    52. Private Sub ListBox_DragDrop(ByVal sender As Object, _
    53.                              ByVal e As DragEventArgs) Handles ListBox1.DragDrop, _
    54.                                                                ListBox2.DragDrop
    55.     Dim source As ListBox = DirectCast(sender, ListBox)
    56.  
    57.     If e.Data.GetDataPresent("System.Windows.Forms.ListBox", False) Then
    58.         'Get the ListBox that the data was dragged from.
    59.         Dim data As ListBox = DirectCast(e.Data.GetData("System.Windows.Forms.ListBox", _
    60.                                                         False),  _
    61.                                          ListBox)
    62.  
    63.         'Make sure we aren't trying to drag from and drop to the same control.
    64.         If data IsNot source Then
    65.             'Get the items that were dragged.
    66.             Dim items As Object() = data.SelectedItems.Cast(Of Object).ToArray()
    67.  
    68.             'Remove the items from their original location.
    69.             For Each item In items
    70.                 data.Items.Remove(item)
    71.             Next
    72.  
    73.             'Get the current mouse location relative to the control being dropped on.
    74.             Dim location As Point = source.PointToClient(New Point(e.X, e.Y))
    75.             Dim dropIndex As Integer = -1
    76.  
    77.             'Find the item over which the mouse was released.
    78.             For index As Integer = 0 To source.Items.Count - 1
    79.                 If source.GetItemRectangle(index).Contains(location) Then
    80.                     dropIndex = index
    81.  
    82.                     Exit For
    83.                 End If
    84.             Next
    85.  
    86.             If dropIndex = -1 Then
    87.                 'The mouse was not released over an item so add the new items to the end.
    88.                 source.Items.AddRange(items)
    89.             Else
    90.                 'Insert the new items above the item they were dropped on.
    91.                 For Each item In items
    92.                     source.Items.Insert(dropIndex, item)
    93.                     dropIndex += 1
    94.                 Next
    95.             End If
    96.         End If
    97.     End If
    98. End Sub
    Last edited by jmcilhinney; Jul 5th, 2015 at 03:06 AM. Reason: Added multi-item example.
    Why is my data not saved to my database? | MSDN Data Walkthroughs
    VBForums Database Development FAQ
    My CodeBank Submissions: VB | C#
    My Blog: Data Among Multiple Forms (3 parts)
    Beginner Tutorials: VB | C# | SQL

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •  



Click Here to Expand Forum to Full Width