【问题标题】:What's special about mouse capture and middle mouse button in WPF?WPF中的鼠标捕获和鼠标中键有什么特别之处?
【发布时间】:2010-06-14 22:02:22
【问题描述】:

当我调用 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 表示已成功获取捕获。

这里发生了什么?这可能是因为我的罗技鼠标驱动程序做了一些愚蠢的事情,试图启动“超滚动”或其他什么?

【问题讨论】:

    标签: wpf


    【解决方案1】:

    这可以通过将调试器设置为中断 UIElement.ReleaseMouseCapture() 方法并查看调用堆栈来诊断。如果你这样做,你会发现是 ListBox 的 OnMouseMove 导致了问题。

    所以你所要做的就是重写 OnMouseMove 并且如果中间按钮被按下则不调用基类:

    public class TestListBox : ListBox 
    { 
      protected override void OnMouseMove(MouseEventArgs e)
      {
        if(Mouse.MiddleButton!=MouseButtonState.Pressed)
          base.OnMouseMove(e);
      }
    }
    

    【讨论】:

    • 谢谢!我正在查看堆栈,它太深了,以至于我没有注意到 OnMouseMove。当然,查看 Reflector 中的 ListBox.OnMouseMove,我发现如果左键未按下,它会释放鼠标捕获。
    【解决方案2】:

    我发现其他人也遇到了同样的问题,并将其缩小到 ListBox 的特定问题。

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

    如果我切换到画布,那么它会按我的预期工作。所以 ListBox 正在做一些捕获。通过使用 Handled=true 的预览处理事情,甚至在不调用基础的情况下覆盖 OnGotMouseCapture 等,都无法解决此问题。

    【讨论】:

      猜你喜欢
      • 2014-04-05
      • 2011-06-29
      • 2010-12-10
      • 1970-01-01
      • 2010-12-26
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2018-10-08
      相关资源
      最近更新 更多