Jump to content
Xtreme .Net Talk

Recommended Posts

Posted

I need to be able to move listbox items around a collection of up to 12 listboxes. For example, I move an item from listbox1 to listbox2; later, I need to move that same item from listbox2 to listbox3, and then on a future date move the item from listbox3 back to listbox1. I also need the item to be removed from its previous location when it moves to a new listbox.

 

Here is the code I have for moving items between 2 listboxes:

 

Private Sub listbox1_MouseDown(ByVal sender As Object, ByVal e As System.Windows.Forms.MouseEventArgs) Handles ListBox1.MouseDown
       If ListBox1.SelectedIndex < 0 Then Return
       ListBox1.DoDragDrop(ListBox1.Items(ListBox1.SelectedIndex).ToString, DragDropEffects.Copy Or DragDropEffects.Move)
   End Sub

   Private Sub listbox2_MouseDown(ByVal sender As Object, ByVal e As System.Windows.Forms.MouseEventArgs) Handles ListBox2.MouseDown
       If ListBox2.SelectedIndex < 0 Then Return
       ListBox2.DoDragDrop(ListBox2.Items(ListBox2.SelectedIndex).ToString, DragDropEffects.Copy Or DragDropEffects.Move)
   End Sub

   Private Sub listbox2_DragEnter(ByVal sender As Object, ByVal e As System.Windows.Forms.DragEventArgs) Handles ListBox2.DragEnter
       e.Effect = DragDropEffects.All
   End Sub

   Private Sub listbox1_DragEnter(ByVal sender As Object, ByVal e As System.Windows.Forms.DragEventArgs) Handles ListBox1.DragEnter
       e.Effect = DragDropEffects.All
   End Sub

   Private Sub listbox2_DragDrop(ByVal sender As Object, ByVal e As System.Windows.Forms.DragEventArgs) Handles ListBox2.DragDrop
       If ListBox2.FindStringExact(e.Data.GetData(DataFormats.Text).ToString) = -1 Then
           ListBox2.Items.Add(e.Data.GetData(DataFormats.Text).ToString)
           ListBox1.Items.Remove(ListBox1.Items(ListBox1.SelectedIndex))
       End If
   End Sub

   Private Sub listbox1_DragDrop(ByVal sender As Object, ByVal e As System.Windows.Forms.DragEventArgs) Handles ListBox1.DragDrop
       If ListBox1.FindStringExact(e.Data.GetData(DataFormats.Text).ToString) = -1 Then
           ListBox1.Items.Add(e.Data.GetData(DataFormats.Text).ToString)
           ListBox2.Items.Remove(ListBox2.Items(ListBox2.SelectedIndex))
       End If
   End Sub

 

This is not original code from me; I got it from another site.

 

I modified this code to include a third listbox, but the modification doesn't remove the item from the its previous listbox (I added the listbox3 "Remove" code to the original DragDrop events and duplicated the MouseDown and DragEnter events); it copies it to the new listbox.

 

I appreciate any help or guidance.

  • Leaders
Posted
You should probably post the actual code you are using so it is easier to see where the problem is. I don't see any references to ListBox3 in what you've got there.
[sIGPIC]e[/sIGPIC]
Posted

Sorry about that.

I solved the lesser problem of doing more than 2 listboxes (it works with 3 listboxes), so I'll post that code. However, this doesn't resolve the larger issue where I need to be able to swap items between 12 listboxes because this code would get ridiculously long.

 

Here is the code:

Private Sub listbox1_MouseDown(ByVal sender As Object, ByVal e As System.Windows.Forms.MouseEventArgs) Handles ListBox1.MouseDown
       If ListBox1.SelectedIndex < 0 Then Return
       ListBox1.DoDragDrop(ListBox1.Items(ListBox1.SelectedIndex).ToString, DragDropEffects.Copy Or DragDropEffects.Move)
   End Sub

   Private Sub listbox2_MouseDown(ByVal sender As Object, ByVal e As System.Windows.Forms.MouseEventArgs) Handles ListBox2.MouseDown
       If ListBox2.SelectedIndex < 0 Then Return
       ListBox2.DoDragDrop(ListBox2.Items(ListBox2.SelectedIndex).ToString, DragDropEffects.Copy Or DragDropEffects.Move)
   End Sub
   Private Sub listbox3_MouseDown(ByVal sender As Object, ByVal e As System.Windows.Forms.MouseEventArgs) Handles ListBox3.MouseDown
       If ListBox3.SelectedIndex < 0 Then Return
       ListBox3.DoDragDrop(ListBox3.Items(ListBox3.SelectedIndex).ToString, DragDropEffects.Copy Or DragDropEffects.Move)
   End Sub

   'These subs allow entrance into the selected listbox

   Private Sub listbox2_DragEnter(ByVal sender As Object, ByVal e As System.Windows.Forms.DragEventArgs) Handles ListBox2.DragEnter
       e.Effect = DragDropEffects.All
   End Sub

   Private Sub listbox1_DragEnter(ByVal sender As Object, ByVal e As System.Windows.Forms.DragEventArgs) Handles ListBox1.DragEnter
       e.Effect = DragDropEffects.All
   End Sub
   Private Sub listbox3_DragEnter(ByVal sender As Object, ByVal e As System.Windows.Forms.DragEventArgs) Handles ListBox3.DragEnter
       e.Effect = DragDropEffects.All
   End Sub

   'These subs allows the cursor to enter the listboxes and drop items into them

   Private Sub listbox2_DragDrop(ByVal sender As Object, ByVal e As System.Windows.Forms.DragEventArgs) Handles ListBox2.DragDrop
       If ListBox2.FindStringExact(e.Data.GetData(DataFormats.Text).ToString) = -1 Then
           ListBox2.Items.Add(e.Data.GetData(DataFormats.Text).ToString)
           If ListBox1.FindStringExact(e.Data.GetData(DataFormats.Text).ToString) <> -1 Then
               ListBox1.Items.Remove(ListBox1.Items(ListBox1.SelectedIndex))
           Else
               ListBox3.Items.Remove(ListBox3.Items(ListBox3.SelectedIndex))
           End If
       End If
   End Sub
   Private Sub listbox1_DragDrop(ByVal sender As Object, ByVal e As System.Windows.Forms.DragEventArgs) Handles ListBox1.DragDrop

       If ListBox1.FindStringExact(e.Data.GetData(DataFormats.Text).ToString) = -1 Then
           ListBox1.Items.Add(e.Data.GetData(DataFormats.Text).ToString)
           If ListBox2.FindStringExact(e.Data.GetData(DataFormats.Text).ToString) <> -1 Then
               ListBox2.Items.Remove(ListBox2.Items(ListBox2.SelectedIndex))
           Else
               ListBox3.Items.Remove(ListBox3.Items(ListBox3.SelectedIndex))
           End If
       End If
   End Sub
   Private Sub listbox3_DragDrop(ByVal sender As Object, ByVal e As System.Windows.Forms.DragEventArgs) Handles ListBox3.DragDrop
       If ListBox3.FindStringExact(e.Data.GetData(DataFormats.Text).ToString) = -1 Then
           ListBox3.Items.Add(e.Data.GetData(DataFormats.Text).ToString)

           If ListBox1.FindStringExact(e.Data.GetData(DataFormats.Text).ToString) <> -1 Then
               ListBox1.Items.Remove(ListBox1.Items(ListBox1.SelectedIndex))
           Else
               ListBox2.Items.Remove(ListBox2.Items(ListBox2.SelectedIndex))
           End If
       End If
   End Sub

 

I would like to be able to work through the different listboxes with a SELECT CASE statement by referencing each lisbox, but I'm not sure how I would do that.

Thanks for any help or guidance.

  • Leaders
Posted (edited)

When the drag operation starts, you can store a reference to the control that started the operation. That way you don't have to go looking for it later on.

Private Sub listbox1_MouseDown(ByVal sender As Object, ByVal e As System.Windows.Forms.MouseEventArgs) Handles ListBox1.MouseDown
   If ListBox1.SelectedIndex < 0 Then Return
   ListBox1.DoDragDrop(ListBox1.Items(ListBox1.SelectedIndex).ToString, DragDropEffects.Copy Or DragDropEffects.Move)
End Sub

becomes...

[color="Blue"]Dim dragSource As ListBox[/color]

Private Sub listbox1_MouseDown(ByVal sender As Object, ByVal e As System.Windows.Forms.MouseEventArgs) Handles ListBox1.MouseDown
   If ListBox1.SelectedIndex < 0 Then Return
   ListBox1.DoDragDrop(ListBox1.Items(ListBox1.SelectedIndex).ToString, DragDropEffects.Copy Or DragDropEffects.Move)
   [color="Green"]'Remember what control the data came from.[/color]
   [color="Blue"]dragSource = ListBox1[/color]
End Sub

But why not generalize it a bit more?

[color="Blue"]Dim dragSource As ListBox[/color]

Private Sub listbox1_MouseDown(ByVal sender As Object, ByVal e As System.Windows.Forms.MouseEventArgs) Handles ListBox1.MouseDown
   [color="Blue"]TryBeginDrag(ListBox1)[/color]
End Sub

[color="Green"]'We can use this sub for any ListBox we want to drag data from[/color]
[color="Blue"]Private Sub TryBeginDrag(source As ListBox)
   If source.SelectedIndex >= 0 Then
       source.DoDragDrop(source.SelectedItem.ToString, DragDropEffects.Copy Or DragDropEffects.Move)    
       dragSource = source
   End If
End Sub[/color]

 

 

Now when we drag and drop to another control, we already know exactly where to remove the string from.

Private Sub listbox2_DragDrop(ByVal sender As Object, ByVal e As System.Windows.Forms.DragEventArgs) Handles ListBox2.DragDrop
   If ListBox2.FindStringExact(e.Data.GetData(DataFormats.Text).ToString) = -1 Then
       ListBox2.Items.Add(e.Data.GetData(DataFormats.Text).ToString)
[color="Blue"]        dragSource.Items.Remove(dragSource.SelectedItem)[/color]
   End If
End Sub

Again, we can generalize:

Private Sub listbox2_DragDrop(ByVal sender As Object, ByVal e As System.Windows.Forms.DragEventArgs) Handles ListBox2.DragDrop
[color="Blue"]    TryDrop(ListBox2, e.Data)[/color]
End Sub

[color="Blue"]
Private Sub TryDrop(destination As ListBox, data As IDataObject)
[color="Green"]    'I find it easier to read my code if I evaluate a large expression outside
   'the if statement and give it a name.[/color]
   Dim destContainsData As Boolean = destination.FindStringExact(data.GetData(DataFormats.Text).ToString()) <> -1

   If Not destContainsData Then
       destination.Items.Add(Data.GetData(DataFormats.Text).ToString)
       dragSource.Items.Remove(dragSource.SelectedItem)
   End If
End Sub
[/color]

 

I haven't tested this code and my VB is a bit rusty, but at the very least you should get the idea. Hope it helps.

Edited by snarfblam
[sIGPIC]e[/sIGPIC]
Posted

Thanks for the help, marble-eater.

 

I'm getting an error in the TryDrop sub. The code is below and the error is at the arrow:

 

Private Sub TryDrop(ByVal destination As ListBox, ByVal data As IDataObject)
       
       Dim destContainsData As Boolean =  destination.FindStringExact(data.GetData(DataFormats.Text).ToString()) <> -1

       If Not destContainsData Then
-->        [b]destination.Items.Add(e.Data.GetData(DataFormats.Text).ToString)[/b]
           dragSource.Items.Remove(dragSource.SelectedItem)
       End If

End Sub

 

Here is the error msg: "Name 'e' is not declared."

 

I tried copying "ByVal e As System.Windows.Forms.DragEventArgs" into the sub declaration, but I got this error msg: "Argument not specified." I also tried to put "ByVal e As System.Windows.Forms.MouseEventArgs", but I got the "Not a member" error msg. I even took the 'e' out; that eliminated the error msg, but the program still did not work properly.

 

Out of curiosity, I answered "Yes" once when asked if I wanted to continue in spite of the error. The program seems to work AFTER the first time I move one item from one listbox to another, but only with the items that have not been moved yet.

 

In case you are wondering, I copied your examples and modified it to work for all the listboxes. Here is the entire code with your modifications:

 

'We can use this sub for any ListBox we want to drag data from
   Private Sub TryBeginDrag(ByVal source As ListBox)
       If source.SelectedIndex > 0 Then
           source.DoDragDrop(source.SelectedItem.ToString, DragDropEffects.Copy Or DragDropEffects.Move)
           dragsource = source
       End If
   End Sub

   Private Sub TryDrop(ByVal destination As ListBox, ByVal data As IDataObject)
       'I find it easier to read my code if I evaluate a large expression outside
       'the if statement and give it a name.
       Dim destContainsData As Boolean = destination.FindStringExact(data.GetData(DataFormats.Text).ToString()) <> -1

       If Not destContainsData Then
-->            destination.Items.Add(e.Data.GetData(DataFormats.Text).ToString)
           dragsource.Items.Remove(dragsource.SelectedItem)
       End If
   End Sub


   '===============================================================================================================================================
   '===============================================================================================================================================

   Private Sub listbox1_MouseDown(ByVal sender As Object, ByVal e As System.Windows.Forms.MouseEventArgs) Handles ListBox1.MouseDown
       TryBeginDrag(ListBox1)
   End Sub
   Private Sub listbox2_MouseDown(ByVal sender As Object, ByVal e As System.Windows.Forms.MouseEventArgs) Handles ListBox2.MouseDown
       TryBeginDrag(ListBox2)
   End Sub
   Private Sub listbox3_MouseDown(ByVal sender As Object, ByVal e As System.Windows.Forms.MouseEventArgs) Handles ListBox3.MouseDown
       TryBeginDrag(ListBox3)
   End Sub

   Private Sub listbox1_DragDrop(ByVal sender As Object, ByVal e As System.Windows.Forms.DragEventArgs) Handles ListBox1.DragDrop
       TryDrop(ListBox1, e.Data)
   End Sub
   Private Sub listbox2_DragDrop(ByVal sender As Object, ByVal e As System.Windows.Forms.DragEventArgs) Handles ListBox2.DragDrop
       TryDrop(ListBox2, e.Data)
   End Sub
   Private Sub listbox3_DragDrop(ByVal sender As Object, ByVal e As System.Windows.Forms.DragEventArgs) Handles ListBox3.DragDrop
       TryDrop(ListBox3, e.Data)
   End Sub


   Private Sub listbox1_DragEnter(ByVal sender As Object, ByVal e As System.Windows.Forms.DragEventArgs) Handles ListBox1.DragEnter
       e.Effect = DragDropEffects.All
   End Sub
   Private Sub listbox2_DragEnter(ByVal sender As Object, ByVal e As System.Windows.Forms.DragEventArgs) Handles ListBox2.DragEnter
       e.Effect = DragDropEffects.All
   End Sub
   Private Sub listbox3_DragEnter(ByVal sender As Object, ByVal e As System.Windows.Forms.DragEventArgs) Handles ListBox3.DragEnter
       e.Effect = DragDropEffects.All
   End Sub

 

Thanks again for any help you can give me.

  • Leaders
Posted

My mistake.

 

 


destination.Items.Add([color="Red"]e.[/color]Data.GetData(DataFormats.Text).ToString)
[/Code]

Should be

[Code]
destination.Items.Add(Data.GetData(DataFormats.Text).ToString)
[/Code]

[sIGPIC]e[/sIGPIC]
Posted

Thanks for the reply.

 

I know my last post was a long one, but somewhere in there I mentioned that I already removed the 'e.' The error goes away, but the program doesn't work properly until after the first time I move an object, and then seemingly stops allowing DragEnter events (You can't move anything into the listboxes; it's as if the AllowDrop property was switched to 'False'). I included the error part in the post with the hope that you saw something you missed.

 

I do appreciate the time you've put into this issue; I'm going to play with it a while and see if I can narrow down what the problem is. I would gladly accept anymore ideas/suggestions you have.

 

Thanks again.

  • Leaders
Posted

Sorry, I guess I didn't read it well enough. Here is what seems to be the problem: I didn't realize that the Control.DoDragDrop method blocks the main thread until the drag and drop operation is complete. This is the corrected code for TryBeginDrag:

   Private Sub TryBeginDrag(ByVal source As ListBox)
       If source.SelectedIndex >= 0 Then
           [color="Red"]dragSource = source[/color] [color="Green"]' moved[/color] 
[color="Green"]            ' This method blocks the main thread[/color] 
          source.DoDragDrop(source.SelectedItem.ToString, DragDropEffects.Copy Or DragDropEffects.Move)
       End If
   End Sub

dragSource needs to be set before calling DoDragDrop. Otherwise it won't get set until after the DragEnter and DragDrop events are raised. I guess I didn't realize that it worked that way because I'm not familiar with DotNet's drag and drop system. I don't use it because it just seems aweful (probably because it just wraps the Windows drag and drop system, which is, presumably, aweful).

[sIGPIC]e[/sIGPIC]
Posted

Excellent, marble-eater! Thanks for figuring that out. I played around with the code for a couple of hours today, but nothing seemed to work.

 

Thanks again for your effort.

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.

Guest
Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

×
×
  • Create New...