Reputation: 14548
When I call CaptureMouse() in response to a MouseDown from the middle mouse button, it will capture and then release the mouse.
Huh?
I've tried using Preview events, setting Handled=true, doesn't make a difference. Am I not understanding mouse capture in WPF?
Here's some minimal sample code that reproduces the problem.
// TestListBox.cs
using System.Diagnostics;
using System.Windows.Controls;
namespace Local
{
public class TestListBox : ListBox
{
public TestListBox()
{
MouseDown += (_, e) =>
{
Debug.WriteLine("+MouseDown");
Debug.WriteLine(" Capture: " + CaptureMouse());
Debug.WriteLine("-MouseDown");
};
GotMouseCapture += (_, e) => Debug.WriteLine("GotMouseCapture");
LostMouseCapture += (_, e) => Debug.WriteLine("LostMouseCapture");
}
}
}
Generating a default WPF app that has this for its main window will use the test class:
<Window x:Class="Local.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="clr-namespace:Local"
Title="MainWindow" Height="350" Width="525">
<local:TestListBox>
<ListBoxItem>1</ListBoxItem>
<ListBoxItem>2</ListBoxItem>
<ListBoxItem>3</ListBoxItem>
<ListBoxItem>4</ListBoxItem>
</local:TestListBox>
</Window>
Upon clicking the middle button down, I get this output:
+MouseDown
GotMouseCapture
LostMouseCapture
Capture: True
-MouseDown
So I'm calling CaptureMouse, which in turn grabs and then releases capture, yet returns true that capture was successfully acquired.
What's going on here? Is it possible that this is something with my Logitech mouse driver doing something goofy, trying to initiate 'ultrascroll' or something?
Upvotes: 2
Views: 1346
Reputation: 62919
This can be diagnosed by setting your debugger to break on UIElement.ReleaseMouseCapture() method and looking at the call stack. If you do this you will find that it is ListBox's OnMouseMove that is causing the problem.
So all you have to do to is override OnMouseMove and not call the base class if the middle button is down:
public class TestListBox : ListBox
{
protected override void OnMouseMove(MouseEventArgs e)
{
if(Mouse.MiddleButton!=MouseButtonState.Pressed)
base.OnMouseMove(e);
}
}
Upvotes: 1
Reputation: 14548
I found someone else had run into the same problem and narrowed it down to a specific issue with ListBox.
If I switch to a Canvas then it works as I expect. So the ListBox is doing something with capture. Handling things via Previews with Handled=true and even overriding OnGotMouseCapture etc. without calling the base does not work around the issue.
Upvotes: 0