Recipe 14.15. Dragging and Dropping Between ListBox Controls


Problem

You have two ListBox controls on a form, and you want the user to be able to drag and drop items between the lists.

Solution

Sample code folder: Chapter 14\DragDropLists

Use code similar to that found in Recipe 14.14 in conjunction with the ListBox control's DoDragDrop() method to enable dragging and dropping between ListBoxes.

Discussion

Create a new Windows Forms application, and add two ListBox controls named ListBox1 and ListBox2 to the form. In both controls, set the AllowDrop property to TRue, and set the SelectionMode property to MultiExtended. In the properties for ListBox1, select the Items property, and click the "…" button in its data value area. In the String Collection Editor window that appears, enter multiple lines of text, separating them by pressing the Enter key. (We entered the words "One" through "Six.") Figure 14-13 shows this process in action.

Figure 14-13. Using the ListBox's String Collection Editor


Close the String Collection Editor; you should have a form that looks like Figure 14-14.

Figure 14-14. Two listboxes with draggable items


Now add the following code to the form:

 Private   dragBounds As Rectangle Private dragMethod As String Private Sub ListBox1_DragEnter(ByVal sender As Object, _       ByVal e As System.Windows.Forms.DragEventArgs) _       Handles ListBox1.DragEnter    ' ----- Yes, we accept the items.    If (e.Data.GetDataPresent(ListBox2.SelectedItems. _          GetType( )) = True) Then _       e.Effect = DragDropEffects.Move End Sub Private Sub ListBox1_DragDrop(ByVal sender As Object, _       ByVal e As System.Windows.Forms.DragEventArgs) _       Handles ListBox1.DragDrop    ' ----- Accept the dropped items.    For Each oneItem As Object In _          e.Data.GetData(ListBox2.SelectedItems.GetType( ))       ListBox1.Items.Add(oneItem)    Next oneItem End Sub Private Sub ListBox1_MouseDown(ByVal sender As Object, _       ByVal e As System.Windows.Forms.MouseEventArgs) _       Handles ListBox1.MouseDown, ListBox2.MouseDown    ' ----- Prepare the draggable content.    If (CType(sender, ListBox).SelectedItems.Count = 0) _       Then Return    ' ----- Don't start the drag yet. Wait until we move a    '       certain amount.    dragBounds = New Rectangle(New Point(e.X - _       (SystemInformation.DragSize.Width / 2), _       e.Y - (SystemInformation.DragSize.Height / 2)), _       SystemInformation.DragSize)    If (sender Is ListBox1) Then       dragMethod = "1to2"    Else       dragMethod = "2to1"    End If End Sub Private Sub ListBox1_MouseMove(ByVal sender As Object, _       ByVal e As System.Windows.Forms.MouseEventArgs) _       Handles ListBox1.MouseMove    ' ----- Ignore if not dragging from ListBox1.    If (dragMethod <> "1to2") Then Return    ' ----- Have we left the drag boundary?    If (dragBounds.Contains(e.X, e.Y) = False) Then       ' ----- Start the drag-and-drop operation.       If (ListBox1.DoDragDrop(ListBox1.SelectedItems, _               DragDropEffects.Move) = _             DragDropEffects.Move) Then          ' ----- Successful move. Remove the items from          '       this list.          Do While ListBox1.SelectedItems.Count > 0             ListBox1.Items.Remove(ListBox1.SelectedItems(0))          Loop       End If       dragMethod = ""    End If End Sub Private Sub ListBox1_MouseUp(ByVal sender As Object, _       ByVal e As System.Windows.Forms.MouseEventArgs) _       Handles ListBox1.MouseUp, ListBox2.MouseUp    ' ----- End of drag-and-drop.    dragMethod = "" End Sub Private Sub ListBox2_DragEnter(ByVal sender As Object, _       ByVal e As System.Windows.Forms.DragEventArgs) _       Handles ListBox2.DragEnter    ' ----- Yes, we accept the items.    If (e.Data.GetDataPresent(ListBox1.SelectedItems. _          GetType( )) = True) Then _        e.Effect = DragDropEffects.Move End Sub Private Sub ListBox2_DragDrop(ByVal sender As Object, _       ByVal e As System.Windows.Forms.DragEventArgs) _       Handles ListBox2.DragDrop    ' ----- Accept the dropped items.    For Each oneItem As Object In _          e.Data.GetData(ListBox1.SelectedItems.GetType( ))       ListBox2.Items.Add(oneItem)    Next oneItem End Sub Private Sub ListBox2_MouseMove(ByVal sender As Object, _       ByVal e As System.Windows.Forms.MouseEventArgs) _       Handles ListBox2.MouseMove    ' ----- Ignore if not dragging from ListBox2.    If (dragMethod <> "2to1") Then Return    ' ----- Have we left the drag boundary?    If (dragBounds.Contains(e.X, e.Y) = False) Then       ' ----- Start the drag-and-drop operation.       If (ListBox2.DoDragDrop(ListBox2.SelectedItems, _             DragDropEffects.Move) = _             DragDropEffects.Move) Then          ' ----- Successful move. Remove the items from          '       this list.          Do While ListBox2.SelectedItems.Count > 0             ListBox2.Items.Remove(ListBox2.SelectedItems(0))          Loop       End If         dragMethod = ""    End If End Sub 

If you look closely at this code, you will find that much of it is replicated. To support two-way dragging, all code that applies to ListBox1 appears again for ListBox2.

Run this program, and then drag items from one listBox to the other. You can also multiselect and move multiple items at once.

Many controls support the DoDragDrop() method. It accepts data content to send and a set of allowed send methods:

 If (SomeControl.DoDragDrop(dataContent, _       DragDropEffects.Move) = DragDropEffects.Move) Then    ' ----- Successful move. End If 

Calling this function is easy, and it can be done at any time. Most of the code in this sample deals with determining what content can be sent and when.

The DragDropEffects enumeration, used for the second DoDragDrop() argument, indicates which operations the supplier of the data is permitting with the supplied content. Its Move, Copy, and Link enumeration members can be joined with a bitwise Or to indicate multiple allowed features:

 ' ----- Allow copy and move. Select Case SomeControl.DoDragDrop(dataContent, _       DragDropEffects.Move Or DragDropEffect.Copy)    Case DragDropEffects.None       ' ----- The target did not accept the content.    Case DragDropEffects.Copy       ' ----- The target copied the content.    Case DragDropEffects.Move       ' ----- The target moved the content. End Select 

See Also

Recipe 14.14 shows you how to accept dragged-and-dropped files in a ListBox.




Visual Basic 2005 Cookbook(c) Solutions for VB 2005 Programmers
Visual Basic 2005 Cookbook: Solutions for VB 2005 Programmers (Cookbooks (OReilly))
ISBN: 0596101775
EAN: 2147483647
Year: 2006
Pages: 400

flylib.com © 2008-2017.
If you may any questions please contact us: flylib@qtcs.net