DragDrop Reorder Listbox items

Ultrawhack

Well-known member
Joined
Jul 5, 2006
Messages
164
Location
Canada
Programming Experience
3-5
Hi,

I use 2 listboxes on my form.
Listbox1 is filled with items from a database.
Listbox2 is filled with items draggeddropped from Listbox1

How can users manually set the order of items in Listbox2 by dragdropping the items. ie: Users can dragdrop item6 and make it item3, etc.

Thanks !
 
OK, I've included the bare minimum required to draw custom cursor with text that is dragged (the example linked above is good but too much for beginner). For the completeness I also post here the previous code including the added dragover-highlighting and select-dragged-when-dropped.
VB.NET:
Sub drawcursor(ByVal text As String, ByVal fnt As Font)
  Dim bmp As New Bitmap(1, 1)
  Dim g As Graphics = Graphics.FromImage(bmp)
  Dim sz As SizeF = g.MeasureString(text, fnt)
  bmp = New Bitmap(CInt(sz.Width), CInt(sz.Height))
  g = Graphics.FromImage(bmp)
  g.Clear(Color.White)
  g.DrawString(text, fnt, Brushes.Black, 0, 0)
  g.Dispose()
  textcursor = New Cursor(bmp.GetHicon)
  bmp.Dispose()
End Sub
 
Dim textcursor As Cursor
 
Private Sub ListBox1_GiveFeedback(ByVal sender As Object, ByVal e As System.Windows.Forms.GiveFeedbackEventArgs) _
Handles ListBox1.GiveFeedback
  If e.Effect = DragDropEffects.Move Then
    e.UseDefaultCursors = False
    System.Windows.Forms.Cursor.Current = textcursor
  End If
End Sub
 
Private Sub ListBox1_MouseDown(ByVal sender As Object, ByVal e As System.Windows.Forms.MouseEventArgs) _
Handles ListBox1.MouseDown
  Dim ix As Integer = ListBox1.IndexFromPoint(e.Location)
  If ix <> -1 Then
    drawcursor(ListBox1.Items(ix).ToString, ListBox1.Font)
    ListBox1.DoDragDrop(ix.ToString, DragDropEffects.Move)
  End If
End Sub
 
Private Sub ListBox1_DragOver(ByVal sender As Object, ByVal e As System.Windows.Forms.DragEventArgs) _
Handles ListBox1.DragOver
  If e.Data.GetDataPresent(DataFormats.Text) Then
    e.Effect = DragDropEffects.Move
    ListBox1.SelectedIndex = ListBox1.IndexFromPoint(ListBox1.PointToClient(New Point(e.X, e.Y)))
  End If
End Sub
 
Private Sub ListBox1_DragDrop(ByVal sender As Object, ByVal e As System.Windows.Forms.DragEventArgs) _
Handles ListBox1.DragDrop
  If e.Data.GetDataPresent(DataFormats.Text) Then
    Dim dix As Integer = CInt(e.Data.GetData(DataFormats.Text))
    Dim ix As Integer = ListBox1.IndexFromPoint(ListBox1.PointToClient(New Point(e.X, e.Y)))
    If ix <> -1 Then
      Dim obj As Object = ListBox1.Items(dix)
      ListBox1.Items.RemoveAt(dix)
      ListBox1.Items.Insert(ix, obj)
      ListBox1.SelectedIndex = ix
    End If
  End If
End Sub
 
I just caught up on this thread. That's great work JohnH.

How can we incorporate this into a 2 listbox scenario where Listbox1 is source items and Listbox2 contains dragged, reordered items ?
 
Last edited:
Hey John,

That's some excellent code- thanks heaps for that. Just FYI, i've fixed a small bug whereby when dragging an item without previously clearing a selected item, the item being dragged is wrong.. the fix was just to unselect all items in the list on the rightclick event, like so:

VB.NET:
   Private Sub List_MouseDown(ByVal sender As Object, ByVal e As System.Windows.Forms.MouseEventArgs) Handles lstSelectedSuburbs.MouseDown, lstUnselectedSuburbs.MouseDown
        ' Make sure this is the right button.
        If e.Button <> MouseButtons.Right Then Exit Sub

        ' Select the item at this point.
        Dim this_list As ListBox = DirectCast(sender, ListBox)

        'Clear selected items - caused problems when trying to drag with other items selected
        this_list.SelectedItems.Clear()

.....

It'd be cool if instead of highlighting the item above which the dragged item will be moved, we could put a red line above that item, but i'm thinking this is impossible as its nto a datagridview and listboxes don't have divisions between items... or something like that... am i correct?

thanks for this awesome code John... added to my toolbox for extensive use later on no doubt :)
greg.
 
Back
Top