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 !
 
Drag and drop uses exactly the same mechanism no what data or object you are dragging and dropping. You handle the MouseDown event, call DoDragDrop and pass the data you want to drag to the first argument. You then handle the DragDrop event of the object you want to be the target and you get the same data back through the e.Data property. It's then just a matter of writing the code to perform the action, in this case remove the selected item and reinsert it at the appropriate position.
 
Just been thinking about this. The list box exposes an indexfrompoint method right? so you will know what item is in relation to the mouse. With that it should just be a matter of inserting that item in at the index less one of the item you are over. Then just shuffle the others in a for next loop or something. I may be way off but thats how i'd approach it to start with.
 
Sending the index retrieved by indexfrompoint works fine, in drop you removeat that index and insert at new index (again from indexfrompoint)
VB.NET:
Expand Collapse Copy
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
    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
  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.Remove(obj)
      ListBox1.Items.Insert(ix, obj)
    End If
  End If
End Sub
 
JohnH, you should be president ! Works great.

I was wondering if there is any way to use highlighting to show where the dragged item will be dropped.

Try dropping any item above the 1st item in the list (to make it the 1st item)
Try dropping any item below the last item in the list (to make it the last item)

Both conditions fail unless one is very precise with mousetip. I can see users getting frustrated. Is there any way to trap and address that?

Thanks again
 
No that is not how it work, you don't have to be precise, you just have to drag an item to the item where you want it to be inserted. Remember there exist no space between the items, the indexes used here are the item indexes, not the position between the items. The dragged item is inserted at the index of the item you currently hover over. If you drop it somewhere over the first item it will be the new first item, if you drop it over the last item it will be the new last item.
To add 'highlighting' you may set selectedindex while dragging, replace the dragover with this:
VB.NET:
Expand Collapse Copy
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
 
Wonderful! The highlighting makes a big difference. One more thing I noticed is that once the item is dropped, the highlighting remains on. After the DragDrop How can I change the highlighting to the Dropped item?

Thanks
 
How to keep the highlighting on the item that was dragged :
VB.NET:
Expand Collapse Copy
[SIZE=2]
...
ListBox1.Items.Remove(obj)
ListBox1.Items.Insert(ix, obj)
ListBox1.SetSelected((ix), [/SIZE][SIZE=2][COLOR=#0000ff]True[/COLOR][/SIZE][SIZE=2])
[/SIZE][SIZE=2][COLOR=#0000ff]...[/COLOR][/SIZE]

 
Last edited by a moderator:
You could also set selectedindex after the insert:
VB.NET:
Expand Collapse Copy
ListBox1.SelectedIndex = ix
 
Having looked at your link in post 5 i noticed that when you drag on that control a nice image of the item you are dragging appears. If you'd like to mimic that behaviour yourself then you'll need to look into the 'OnGiveFeedback' event. It's there that you can specify a custom cursor to display whilst dragging.
 
Back
Top