|
-
Dec 7th, 2007, 03:07 PM
#1
Thread Starter
Lively Member
[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.
-
Dec 7th, 2007, 08:54 PM
#2
Re: [2005] Drag & Drop Multiple Selections from a ListBox
could you post your code?
-
Dec 9th, 2007, 11:36 AM
#3
Thread Starter
Lively Member
Re: [2005] Drag & Drop Multiple Selections from a ListBox
 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:
Public Class Form1
Private Sub ListBox1_MouseDown(ByVal sender As Object, ByVal e As System.Windows.Forms.MouseEventArgs) Handles ListBox1.MouseDown
ListBox1.DoDragDrop(ListBox1.SelectedItems, DragDropEffects.Move)
End Sub
Private Sub ListBox2_DragDrop(ByVal sender As Object, ByVal e As System.Windows.Forms.DragEventArgs) Handles ListBox2.DragDrop
For Each item As Object In (e.Data.GetData(GetType(ListBox.SelectedObjectCollection)))
ListBox2.Items.Add(item)
Next
End Sub
Private Sub ListBox2_DragOver(ByVal sender As Object, ByVal e As System.Windows.Forms.DragEventArgs) Handles ListBox2.DragOver
If (e.Data.GetDataPresent(GetType(ListBox.SelectedObjectCollection))) Then
e.Effect = DragDropEffects.Move
Else
e.Effect = DragDropEffects.None
End If
End Sub
Private Sub Form1_Load(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Load
Dim items() As String = {"ONE", "TWO", "THREE", "FOUR", "FIVE"}
ListBox1.Items.AddRange(items)
ListBox1.SelectionMode = SelectionMode.MultiExtended
End Sub
End Class
-
Dec 9th, 2007, 06:55 PM
#4
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
-
Dec 10th, 2007, 01:22 PM
#5
Thread Starter
Lively Member
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:
Public Class MultiSelListBox
Inherits ListBox
Private MouseOverIndex As Integer
Private DownOnIndex As Integer
Private Const WM_LBUTTONDOWN As Integer = &H201
Private Const WM_RBUTTONDOWN As Integer = &H204
Private Const WM_LBUTTONUP As Integer = &H202
Private Const WM_RBUTTONUP As Integer = &H205
Protected Overrides Sub WndProc(ByRef m As System.Windows.Forms.Message)
Select Case m.Msg
Case WM_LBUTTONDOWN
DownOnIndex = MouseOverIndex
If Me.SelectedItems.Count >= 1 And Me.SelectedIndices.Contains(MouseOverIndex) Then
Me.DoDragDrop(Me.SelectedItems, DragDropEffects.Move)
Return
Else
MyBase.WndProc(m)
End If
Case WM_LBUTTONUP
If DownOnIndex = MouseOverIndex Then
Dim down As New Message()
down.HWnd = m.HWnd
down.Msg = WM_LBUTTONDOWN
down.WParam = m.WParam
down.LParam = m.LParam
down.Result = IntPtr.Zero
MyBase.WndProc(down)
End If
MyBase.WndProc(m)
Case Else
MyBase.WndProc(m)
End Select
End Sub
Protected Overrides Sub OnMouseMove(ByVal e As System.Windows.Forms.MouseEventArgs)
MouseOverIndex = Me.IndexFromPoint(e.Location)
MyBase.OnMouseMove(e)
End Sub
End Class
Last edited by Nihilistic Mystic; Dec 10th, 2007 at 01:31 PM.
-
Dec 10th, 2007, 01:39 PM
#6
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
-
Dec 10th, 2007, 02:05 PM
#7
Thread Starter
Lively Member
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:
Public Class MultiSelListBox
Inherits ListBox
Private MouseOverIndex As Integer
Private MouseDownIndex As Integer
Private bMouseDownonSelection As Boolean
Private Const WM_LBUTTONDOWN As Integer = &H201
Private Const WM_RBUTTONDOWN As Integer = &H204
Private Const WM_LBUTTONUP As Integer = &H202
Private Const WM_RBUTTONUP As Integer = &H205
Private Const WM_MOUSEMOVE As Integer = &H200
Protected Overrides Sub WndProc(ByRef m As System.Windows.Forms.Message)
Select Case m.Msg
Case WM_LBUTTONDOWN
MouseDownIndex = MouseOverIndex
If Me.SelectedItems.Count >= 1 And Me.SelectedIndices.Contains(MouseOverIndex) Then
bMouseDownonSelection = True
Return
Else
MyBase.WndProc(m)
End If
Case WM_MOUSEMOVE
If bMouseDownonSelection Then
Me.DoDragDrop(Me.SelectedItems, DragDropEffects.Move)
End If
bMouseDownonSelection = False
MyBase.WndProc(m)
Case WM_LBUTTONUP
If MouseDownIndex = MouseOverIndex Then
Dim down As New Message()
down.HWnd = m.HWnd
down.Msg = WM_LBUTTONDOWN
down.WParam = m.WParam
down.LParam = m.LParam
down.Result = IntPtr.Zero
MyBase.WndProc(down)
End If
MyBase.WndProc(m)
Case Else
MyBase.WndProc(m)
End Select
End Sub
Protected Overrides Sub OnMouseMove(ByVal e As System.Windows.Forms.MouseEventArgs)
MouseOverIndex = Me.IndexFromPoint(e.Location)
MyBase.OnMouseMove(e)
End Sub
End Class
-
Dec 10th, 2007, 02:10 PM
#8
Re: [2005] Drag & Drop Multiple Selections from a ListBox
have you tried it with multisimple selection?
-
Dec 10th, 2007, 03:30 PM
#9
Thread Starter
Lively Member
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?
-
Dec 10th, 2007, 03:47 PM
#10
Re: [2005] Drag & Drop Multiple Selections from a ListBox
modifier keys can be got with
vb Code:
Public Declare Function GetAsyncKeyState Lib "user32" Alias "GetAsyncKeyState" (ByVal vKey As Integer) As Integer
-
Dec 10th, 2007, 04:31 PM
#11
Thread Starter
Lively Member
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:
Public Class MultiSelListBox
Inherits ListBox
Private MouseDownOnIndex As Integer
Private bMouseDownOnSelection As Boolean
Private bMouseDownOutsideSelection As Boolean
Private Const WM_LBUTTONDOWN As Integer = &H201
Private Const WM_LBUTTONUP As Integer = &H202
Private Const WM_MOUSEMOVE As Integer = &H200
Private Const MK_LBUTTON As Integer = &H1&
Protected Overrides Sub WndProc(ByRef m As System.Windows.Forms.Message)
Select Case m.Msg
Case WM_LBUTTONDOWN
Dim pt As New Point(m.LParam.ToInt32)
MouseDownOnIndex = Me.IndexFromPoint(pt)
If Me.SelectedItems.Count >= 1 _
And Me.SelectedIndices.Contains(MouseDownOnIndex) _
And m.WParam = MK_LBUTTON Then
bMouseDownonSelection = True
Return
Else
bMouseDownOutsideSelection = True
MyBase.WndProc(m)
End If
Case WM_MOUSEMOVE
If bMouseDownonSelection Then
Me.DoDragDrop(Me.SelectedItems, DragDropEffects.Move)
End If
bMouseDownonSelection = False
MyBase.WndProc(m)
Case WM_LBUTTONUP
Dim pt As New Point(m.LParam.ToInt32)
If MouseDownOnIndex = Me.IndexFromPoint(pt) _
And m.WParam = 0 And Not bMouseDownOutsideSelection Then
Dim down As New Message()
down.HWnd = m.HWnd
down.Msg = WM_LBUTTONDOWN
down.WParam = m.WParam
down.LParam = m.LParam
down.Result = IntPtr.Zero
MyBase.WndProc(down)
End If
bMouseDownOutsideSelection = False
MyBase.WndProc(m)
Case Else
MyBase.WndProc(m)
End Select
End Sub
End Class
-
Dec 10th, 2007, 06:50 PM
#12
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
-
Forum Rules
|
Click Here to Expand Forum to Full Width
|