Results 1 to 12 of 12

Thread: [RESOLVED] [2005] Drag & Drop Multiple Selections from a ListBox

  1. #1

    Thread Starter
    Lively Member
    Join Date
    Jul 2007
    Posts
    85

    Resolved [RESOLVED] [2005] Drag & Drop Multiple Selections from a ListBox

    I have a form with several Listboxes. Two of them are setup as MultiSelect and I have coded DragDrop events to move objects between them, which all works great when a single item is selected.
    The problem I am having is that the listbox control changes selection when the left mouse button goes down, clearing other selected items. I can drag multiple items if I right click drag the selection, but this seems counter intuitive for the user.
    Does anyone have any suggestions on changing this behavior? I assume this could be changed in a custom derived listbox control, but I am not sure how to go about doing that.
    Last edited by Nihilistic Mystic; Dec 7th, 2007 at 03:34 PM.

  2. #2
    eXtreme Programmer .paul.'s Avatar
    Join Date
    May 2007
    Location
    Chelmsford UK
    Posts
    26,413

    Re: [2005] Drag & Drop Multiple Selections from a ListBox

    could you post your code?

  3. #3

    Thread Starter
    Lively Member
    Join Date
    Jul 2007
    Posts
    85

    Re: [2005] Drag & Drop Multiple Selections from a ListBox

    Quote Originally Posted by .paul.
    could you post your code?
    Here is a simple demo of the issue. it's not a problem with the drag drop drop code, it's the Listbox itself. It appears that *before* the mousedown event of a left click the listbox selection changes making it impossible to drag multiple selections with the left mouse button. You can drag multiple selections with the right button.
    Add 2 listboxes to a form and try it out.
    vb.net Code:
    1. Public Class Form1
    2.     Private Sub ListBox1_MouseDown(ByVal sender As Object, ByVal e As System.Windows.Forms.MouseEventArgs) Handles ListBox1.MouseDown
    3.         ListBox1.DoDragDrop(ListBox1.SelectedItems, DragDropEffects.Move)
    4.     End Sub
    5.     Private Sub ListBox2_DragDrop(ByVal sender As Object, ByVal e As System.Windows.Forms.DragEventArgs) Handles ListBox2.DragDrop
    6.         For Each item As Object In (e.Data.GetData(GetType(ListBox.SelectedObjectCollection)))
    7.             ListBox2.Items.Add(item)
    8.         Next
    9.     End Sub
    10.     Private Sub ListBox2_DragOver(ByVal sender As Object, ByVal e As System.Windows.Forms.DragEventArgs) Handles ListBox2.DragOver
    11.         If (e.Data.GetDataPresent(GetType(ListBox.SelectedObjectCollection))) Then
    12.             e.Effect = DragDropEffects.Move
    13.         Else
    14.             e.Effect = DragDropEffects.None
    15.         End If
    16.     End Sub
    17.     Private Sub Form1_Load(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Load
    18.         Dim items() As String = {"ONE", "TWO", "THREE", "FOUR", "FIVE"}
    19.         ListBox1.Items.AddRange(items)
    20.         ListBox1.SelectionMode = SelectionMode.MultiExtended
    21.     End Sub
    22. End Class

  4. #4
    eXtreme Programmer .paul.'s Avatar
    Join Date
    May 2007
    Location
    Chelmsford UK
    Posts
    26,413

    Re: [2005] Drag & Drop Multiple Selections from a ListBox

    thats a difficult one.
    you might be able to catch the listbox mousedown message in a wndProc, and deal with it there

  5. #5

    Thread Starter
    Lively Member
    Join Date
    Jul 2007
    Posts
    85

    Re: [2005] Drag & Drop Multiple Selections from a ListBox

    I have managed to get pretty close to what I wanted. The only issue now is if you have a mulitple selection and want to select a single item within that selection you have to double click or click on another item outside of the selection because it seems that after a DoDrapDrop you can no longer see the WM_LBUTTONUP message. I think I can live with that, hopeuflly I dont get any user complaints.

    vb.net Code:
    1. Public Class MultiSelListBox
    2.     Inherits ListBox
    3.     Private MouseOverIndex As Integer
    4.     Private DownOnIndex As Integer
    5.     Private Const WM_LBUTTONDOWN As Integer = &H201
    6.     Private Const WM_RBUTTONDOWN As Integer = &H204
    7.     Private Const WM_LBUTTONUP As Integer = &H202
    8.     Private Const WM_RBUTTONUP As Integer = &H205
    9.     Protected Overrides Sub WndProc(ByRef m As System.Windows.Forms.Message)
    10.         Select Case m.Msg
    11.             Case WM_LBUTTONDOWN
    12.                 DownOnIndex = MouseOverIndex
    13.                 If Me.SelectedItems.Count >= 1 And Me.SelectedIndices.Contains(MouseOverIndex) Then
    14.                     Me.DoDragDrop(Me.SelectedItems, DragDropEffects.Move)
    15.                     Return
    16.                 Else
    17.                     MyBase.WndProc(m)
    18.                 End If
    19.             Case WM_LBUTTONUP
    20.                 If DownOnIndex = MouseOverIndex Then
    21.                     Dim down As New Message()
    22.                     down.HWnd = m.HWnd
    23.                     down.Msg = WM_LBUTTONDOWN
    24.                     down.WParam = m.WParam
    25.                     down.LParam = m.LParam
    26.                     down.Result = IntPtr.Zero
    27.                     MyBase.WndProc(down)
    28.                 End If
    29.                 MyBase.WndProc(m)
    30.             Case Else
    31.                 MyBase.WndProc(m)
    32.         End Select
    33.     End Sub
    34.     Protected Overrides Sub OnMouseMove(ByVal e As System.Windows.Forms.MouseEventArgs)
    35.         MouseOverIndex = Me.IndexFromPoint(e.Location)
    36.         MyBase.OnMouseMove(e)
    37.     End Sub
    38. End Class
    Last edited by Nihilistic Mystic; Dec 10th, 2007 at 01:31 PM.

  6. #6
    eXtreme Programmer .paul.'s Avatar
    Join Date
    May 2007
    Location
    Chelmsford UK
    Posts
    26,413

    Re: [2005] Drag & Drop Multiple Selections from a ListBox

    thanks for posting it.
    i couldn't work it out.
    i'll have another look at it later

  7. #7

    Thread Starter
    Lively Member
    Join Date
    Jul 2007
    Posts
    85

    Smile Re: [2005] Drag & Drop Multiple Selections from a ListBox

    I think I got it now. Moved the DoDragDrop so that it only fires if the mouse is down and moving so I can still receive the LBUTTONUP message

    vb.net Code:
    1. Public Class MultiSelListBox
    2.     Inherits ListBox
    3.     Private MouseOverIndex As Integer
    4.     Private MouseDownIndex As Integer
    5.     Private bMouseDownonSelection As Boolean
    6.     Private Const WM_LBUTTONDOWN As Integer = &H201
    7.     Private Const WM_RBUTTONDOWN As Integer = &H204
    8.     Private Const WM_LBUTTONUP As Integer = &H202
    9.     Private Const WM_RBUTTONUP As Integer = &H205
    10.     Private Const WM_MOUSEMOVE As Integer = &H200
    11.     Protected Overrides Sub WndProc(ByRef m As System.Windows.Forms.Message)
    12.         Select Case m.Msg
    13.             Case WM_LBUTTONDOWN
    14.                 MouseDownIndex = MouseOverIndex
    15.                 If Me.SelectedItems.Count >= 1 And Me.SelectedIndices.Contains(MouseOverIndex) Then
    16.                     bMouseDownonSelection = True
    17.                     Return
    18.                 Else
    19.                     MyBase.WndProc(m)
    20.                 End If
    21.             Case WM_MOUSEMOVE
    22.                 If bMouseDownonSelection Then
    23.                     Me.DoDragDrop(Me.SelectedItems, DragDropEffects.Move)
    24.                 End If
    25.                 bMouseDownonSelection = False
    26.                 MyBase.WndProc(m)
    27.             Case WM_LBUTTONUP
    28.                 If MouseDownIndex = MouseOverIndex Then
    29.                     Dim down As New Message()
    30.                     down.HWnd = m.HWnd
    31.                     down.Msg = WM_LBUTTONDOWN
    32.                     down.WParam = m.WParam
    33.                     down.LParam = m.LParam
    34.                     down.Result = IntPtr.Zero
    35.                     MyBase.WndProc(down)
    36.                 End If
    37.                 MyBase.WndProc(m)
    38.             Case Else
    39.                 MyBase.WndProc(m)
    40.         End Select
    41.     End Sub
    42.     Protected Overrides Sub OnMouseMove(ByVal e As System.Windows.Forms.MouseEventArgs)
    43.         MouseOverIndex = Me.IndexFromPoint(e.Location)
    44.         MyBase.OnMouseMove(e)
    45.     End Sub
    46. End Class

  8. #8
    eXtreme Programmer .paul.'s Avatar
    Join Date
    May 2007
    Location
    Chelmsford UK
    Posts
    26,413

    Re: [2005] Drag & Drop Multiple Selections from a ListBox

    have you tried it with multisimple selection?

  9. #9

    Thread Starter
    Lively Member
    Join Date
    Jul 2007
    Posts
    85

    Re: [2005] Drag & Drop Multiple Selections from a ListBox

    Wow, that does't work at all, and I have noticed it messes up Ctrl Clicking in MutliExtended... Is there anyway of getting the modifier key state from the WndProc?

  10. #10
    eXtreme Programmer .paul.'s Avatar
    Join Date
    May 2007
    Location
    Chelmsford UK
    Posts
    26,413

    Re: [2005] Drag & Drop Multiple Selections from a ListBox

    modifier keys can be got with

    vb Code:
    1. Public Declare Function GetAsyncKeyState Lib "user32" Alias "GetAsyncKeyState" (ByVal vKey As Integer) As Integer

  11. #11

    Thread Starter
    Lively Member
    Join Date
    Jul 2007
    Posts
    85

    Re: [2005] Drag & Drop Multiple Selections from a ListBox

    Actually I found out they are in the WParam property of the message. I also figured out how to get the mouse location from the LParam property so I got rid of the hacky MouseOver override. I fixed it so that it works with MultiSimple as well.

    vb.net Code:
    1. Public Class MultiSelListBox
    2.     Inherits ListBox
    3.  
    4.     Private MouseDownOnIndex As Integer
    5.     Private bMouseDownOnSelection As Boolean
    6.     Private bMouseDownOutsideSelection As Boolean
    7.     Private Const WM_LBUTTONDOWN As Integer = &H201
    8.     Private Const WM_LBUTTONUP As Integer = &H202
    9.     Private Const WM_MOUSEMOVE As Integer = &H200
    10.     Private Const MK_LBUTTON As Integer = &H1&
    11.  
    12.     Protected Overrides Sub WndProc(ByRef m As System.Windows.Forms.Message)
    13.         Select Case m.Msg
    14.             Case WM_LBUTTONDOWN
    15.                 Dim pt As New Point(m.LParam.ToInt32)
    16.                 MouseDownOnIndex = Me.IndexFromPoint(pt)
    17.                 If Me.SelectedItems.Count >= 1 _
    18.                 And Me.SelectedIndices.Contains(MouseDownOnIndex) _
    19.                 And m.WParam = MK_LBUTTON Then
    20.                     bMouseDownonSelection = True
    21.                     Return
    22.                 Else
    23.                     bMouseDownOutsideSelection = True
    24.                     MyBase.WndProc(m)
    25.                 End If
    26.             Case WM_MOUSEMOVE
    27.                 If bMouseDownonSelection Then
    28.                     Me.DoDragDrop(Me.SelectedItems, DragDropEffects.Move)
    29.                 End If
    30.                 bMouseDownonSelection = False
    31.                 MyBase.WndProc(m)
    32.             Case WM_LBUTTONUP
    33.                 Dim pt As New Point(m.LParam.ToInt32)
    34.                 If MouseDownOnIndex = Me.IndexFromPoint(pt) _
    35.                 And m.WParam = 0 And Not bMouseDownOutsideSelection Then
    36.                     Dim down As New Message()
    37.                     down.HWnd = m.HWnd
    38.                     down.Msg = WM_LBUTTONDOWN
    39.                     down.WParam = m.WParam
    40.                     down.LParam = m.LParam
    41.                     down.Result = IntPtr.Zero
    42.                     MyBase.WndProc(down)
    43.                 End If
    44.                 bMouseDownOutsideSelection = False
    45.                 MyBase.WndProc(m)
    46.             Case Else
    47.                 MyBase.WndProc(m)
    48.         End Select
    49.     End Sub
    50. End Class

  12. #12
    eXtreme Programmer .paul.'s Avatar
    Join Date
    May 2007
    Location
    Chelmsford UK
    Posts
    26,413

    Re: [2005] Drag & Drop Multiple Selections from a ListBox

    excellent. i reckon you can mark that resolved

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