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); 
    } 
} 
+0

谢谢!我正在看栈,它很深,我没有注意到OnMouseMove。当然,在Reflector中查看ListBox.OnMouseMove,我发现如果左按钮没有关闭,它会释放鼠标捕获。 – scobi 2010-06-15 17:48:21

我发现有人遇到同样的问题,并缩小到ListBox的特定问题。

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

如果我切换到画布,然后它工作如我所料。所以列表框正在做一些捕获。通过预处理Handle = true来处理事物,甚至在不调用基地的情况下重写OnGotMouseCapture等都不能解决问题。