2010-06-14 48 views
2

當我通過鼠標中鍵調用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'或其他?

回答

1

這可以通過設置您的調試器在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