WPF中鼠标捕获和鼠标中键的特殊之处是什么?

时间:2010-06-14 22:02:23

标签: wpf

当我从中鼠标按钮调用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'之类的事情吗?

2 个答案:

答案 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的特定问题。

http://social.msdn.microsoft.com/Forums/en/wpf/thread/5487c21a-1527-4a4f-bdf5-62de921d2ae0?prof=required

如果我切换到Canvas,那么它可以正常工作。所以ListBox正在做一些捕获。通过Previews with Handled = true处理事物,甚至覆盖OnGotMouseCapture等而不调用base不会解决问题。