WPF中的鼠标捕捉和中键鼠标有什么特别之处?
问题描述:
当我通过鼠标中键调用CaptureMouse()来响应MouseDown时,它将捕获并释放鼠标。WPF中的鼠标捕捉和中键鼠标有什么特别之处?
咦?
我试过使用预览事件,设置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,然后抓取然后释放捕获,然后返回真实的捕获成功获得。
这是怎么回事?这可能是我的Logitech鼠标驱动程序做了一些愚蠢的事情,尝试启动'ultrascroll'或其他?
答
这可以通过设置您的调试器在UIElement.ReleaseMouseCapture()方法中断并查看调用堆栈来诊断。如果你这样做,你会发现它是导致问题的ListBox的OnMouseMove。
因此,所有你需要做的是重写的OnMouseMove而不是调用基类,如果中间的按钮是向下:
public class TestListBox : ListBox
{
protected override void OnMouseMove(MouseEventArgs e)
{
if(Mouse.MiddleButton!=MouseButtonState.Pressed)
base.OnMouseMove(e);
}
}
答
我发现有人遇到同样的问题,并缩小到ListBox的特定问题。
如果我切换到画布,然后它工作如我所料。所以列表框正在做一些捕获。通过预处理Handle = true来处理事物,甚至在不调用基地的情况下重写OnGotMouseCapture等都不能解决问题。
谢谢!我正在看栈,它很深,我没有注意到OnMouseMove。当然,在Reflector中查看ListBox.OnMouseMove,我发现如果左按钮没有关闭,它会释放鼠标捕获。 – scobi 2010-06-15 17:48:21