Strange order of events in ListView with MultiSelect set to false
-
I noticed a weird behaviour in
ListView
. When itsMultiSelect
property is set totrue
and I press a mouse button while the cursor is inside the control, I get aMouseDown
event. Then I release the button and get aMouseUp
event, just as I would expect. However, when I set theMultiSelect
property tofalse
and press a mouse button, I suddenly get theMouseUp
event immediately after theMouseDown
one. When I then actually release the button, noMouseUp
fires. Is this intentional? How can I then properly determine when the mouse button was actually released? -
I noticed a weird behaviour in
ListView
. When itsMultiSelect
property is set totrue
and I press a mouse button while the cursor is inside the control, I get aMouseDown
event. Then I release the button and get aMouseUp
event, just as I would expect. However, when I set theMultiSelect
property tofalse
and press a mouse button, I suddenly get theMouseUp
event immediately after theMouseDown
one. When I then actually release the button, noMouseUp
fires. Is this intentional? How can I then properly determine when the mouse button was actually released? -
I noticed a weird behaviour in
ListView
. When itsMultiSelect
property is set totrue
and I press a mouse button while the cursor is inside the control, I get aMouseDown
event. Then I release the button and get aMouseUp
event, just as I would expect. However, when I set theMultiSelect
property tofalse
and press a mouse button, I suddenly get theMouseUp
event immediately after theMouseDown
one. When I then actually release the button, noMouseUp
fires. Is this intentional? How can I then properly determine when the mouse button was actually released?I can confirm what you are experiencing - this only occurs when the control itself is clicked. When a
ListViewItem
is clicked (MouseDown
) the behaviour is normal (even if the mouse is moved away from the clicked item). Very odd. :confused:Dave
If this helped, please vote & accept answer!
Binging is like googling, it just feels dirtier. Please take your VB.NET out of our nice case sensitive forum.(Pete O'Hanlon)
BTW, in software, hope and pray is not a viable strategy. (Luc Pattyn) -
I noticed a weird behaviour in
ListView
. When itsMultiSelect
property is set totrue
and I press a mouse button while the cursor is inside the control, I get aMouseDown
event. Then I release the button and get aMouseUp
event, just as I would expect. However, when I set theMultiSelect
property tofalse
and press a mouse button, I suddenly get theMouseUp
event immediately after theMouseDown
one. When I then actually release the button, noMouseUp
fires. Is this intentional? How can I then properly determine when the mouse button was actually released?This is a semi-solution. Subclassing the
ListView
and overridingWndProc
, listen for the left mouse button up message and raise theMouseUp
event passing the correct parameters. With a bit more work you may be able to use a flag to allow/disallowMouseUp
messages to supress the erroneous one that you are getting.public class FixedListView : ListView { private const int WM\_LBUTTONUP = 0x0202; protected override void WndProc(ref Message m) { if (m.Msg == WM\_LBUTTONUP) { // adjusting as X and Y are 16 bits each of LParam Point point = new Point(((int)m.LParam) & 0x0000FFFF, (int)m.LParam >> 16); OnMouseUp(new MouseEventArgs(MouseButtons.Left, 1, point.X, point.Y, 0)); return; } base.WndProc(ref m); } }
Dave
If this helped, please vote & accept answer!
Binging is like googling, it just feels dirtier. Please take your VB.NET out of our nice case sensitive forum.(Pete O'Hanlon)
BTW, in software, hope and pray is not a viable strategy. (Luc Pattyn) -
I can confirm what you are experiencing - this only occurs when the control itself is clicked. When a
ListViewItem
is clicked (MouseDown
) the behaviour is normal (even if the mouse is moved away from the clicked item). Very odd. :confused:Dave
If this helped, please vote & accept answer!
Binging is like googling, it just feels dirtier. Please take your VB.NET out of our nice case sensitive forum.(Pete O'Hanlon)
BTW, in software, hope and pray is not a viable strategy. (Luc Pattyn)Yes, that's true, unfortunately I need to properly handle all clicks in the control, not just those on a
ListViewItem
. It even doesn't work on aListViewSubItem
. -
Yes, that's true, unfortunately I need to properly handle all clicks in the control, not just those on a
ListViewItem
. It even doesn't work on aListViewSubItem
.It works on sub items if you set FullRowSelect to true... wired bahavior...
-
This is a semi-solution. Subclassing the
ListView
and overridingWndProc
, listen for the left mouse button up message and raise theMouseUp
event passing the correct parameters. With a bit more work you may be able to use a flag to allow/disallowMouseUp
messages to supress the erroneous one that you are getting.public class FixedListView : ListView { private const int WM\_LBUTTONUP = 0x0202; protected override void WndProc(ref Message m) { if (m.Msg == WM\_LBUTTONUP) { // adjusting as X and Y are 16 bits each of LParam Point point = new Point(((int)m.LParam) & 0x0000FFFF, (int)m.LParam >> 16); OnMouseUp(new MouseEventArgs(MouseButtons.Left, 1, point.X, point.Y, 0)); return; } base.WndProc(ref m); } }
Dave
If this helped, please vote & accept answer!
Binging is like googling, it just feels dirtier. Please take your VB.NET out of our nice case sensitive forum.(Pete O'Hanlon)
BTW, in software, hope and pray is not a viable strategy. (Luc Pattyn)Thanks for the proposed semi-solution. I put together different pieces and came up with this solution which seems to do what I want :) First, I leave the
MultiSelect
property set tofalse
and setFullRowSelect
totrue
. Then I use this code:public class CustomListView : ListView
{
public CustomListView()
{
InitializeComponent();
}bool fakeMouseUp = false; bool mouseDownOnItem = false; protected override void OnMouseDown( MouseEventArgs e ) { // if we're not on an item or subitem, we will get OnMouseUp immediately mouseDownOnItem = HitTest( e.Location ).Item != null; Debug.WriteLine( "OnMouseDown" ); base.OnMouseDown( e ); } protected override void OnMouseUp( MouseEventArgs e ) { if( mouseDownOnItem || fakeMouseUp ) { Debug.WriteLine( "OnMouseUp" ); mouseDownOnItem = false; fakeMouseUp = false; base.OnMouseUp( e ); } } protected override void WndProc( ref Message m ) { if( !mouseDownOnItem && m.Msg == 0x0202 /\*WM\_LBUTTONUP\*/ ) { // send a fake MouseUp event fakeMouseUp = true; Point point = new Point( ((int) m.LParam) & 0x0000FFFF, (int) m.LParam >> 16 ); OnMouseUp( new MouseEventArgs( MouseButtons.Left, 1, point.X, point.Y, 0 ) ); } base.WndProc( ref m ); }
}
But I always have a feeling of wasted time when I need to do such workarounds for weird .NET behaviour. Why on Earth do I get a
MouseUp
event when the mouse button was not physically released? :confused: