当我从中鼠标按钮调用CaptureMouse()以响应MouseDown时,它将捕获然后释放鼠标。
咦?
我尝试过使用预览事件,设置Handled = true,没有什么区别。我不理解WPF中的鼠标捕获吗?
这是一些可以重现问题的最小示例代码。
// 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");
}
}
}
为其主窗口生成一个默认的WPF应用程序将使用测试类:
<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>
点击中间按钮后,我得到了这个输出:
+MouseDown
GotMouseCapture
LostMouseCapture
Capture: True
-MouseDown
所以我正在调用CaptureMouse,后者又会抓取然后释放捕获,但返回true表示已成功获取捕获。
这里发生了什么?这可能是我的罗技鼠标驱动程序做了一些傻瓜,尝试启动'ultrascroll'之类的事情吗?
答案 0 :(得分:1)
这可以通过将调试器设置为在UIElement.ReleaseMouseCapture()方法上中断并查看调用堆栈来诊断。如果你这样做,你会发现导致问题的是ListBox的OnMouseMove。
所以你要做的就是覆盖OnMouseMove,如果中间按钮关闭,则不调用基类:
public class TestListBox : ListBox
{
protected override void OnMouseMove(MouseEventArgs e)
{
if(Mouse.MiddleButton!=MouseButtonState.Pressed)
base.OnMouseMove(e);
}
}
答案 1 :(得分:0)
我发现其他人遇到了同样的问题,并将其缩小到ListBox的特定问题。
如果我切换到Canvas,那么它可以正常工作。所以ListBox正在做一些捕获。通过Previews with Handled = true处理事物,甚至覆盖OnGotMouseCapture等而不调用base不会解决问题。