2010-11-26 46 views
0

我在VS 2010中寫了一個非常小的WPF + Rx程序,它有一些意想不到的行爲 - 看起來像是在鼠標事件中觀察到了alt-key事件。我會很感激的意見對任何奇怪的事件串擾:鼠標和鍵盤,WPF和Rx?

  1. 有什麼具體錯誤就如何進一步診斷對我自己[例如
  2. 想法或工具,還有一些工具,儀器儀表的代碼來跟蹤並記錄所有事件被解僱,所以我可以更清楚地看到發生了什麼?]
  3. 如何理解行爲 - 是「通過設計」?我是否濫用WPF或Rx或兩者?
  4. 怎麼弄的行爲,我寧願有,下面

首先描述的內容,它正確地做是從鼠標開始向下,並用鼠標向上結束火鼠標移動觀察員。我剛纔在Window的TitleBar中放置了正確的mouseDown + mouseUp座標(參見下面的代碼+ XAML)。

如果我在鼠標關閉時按下並釋放alt鍵,則會出現奇怪現象。這似乎立即停止mouseMove事件觀察員。現在,如果我釋放mouseButton,則mouseMove事件觀察者再次啓動,並繼續,直到我生成新的mouseDown或再次按下並釋放alt。更進一步,如果我去通過這個序列,即

mouseDown 
mouseMove 
alt-key down 
alt-key up 
mouseUp 
alt-key down 
alt-key up 

,然後在標題欄中的正常

mouseDown 
mouseMove 

打印有一些奇怪的閃爍,告訴我,還有其他的,外來的事件通過我的觀察員lambda獲得跟蹤和泵送。

我還沒有能夠通過alt以外的其他鍵來使這個失敗,加深了這個謎。

期望的行爲可能是

  1. 明確地在鼠標移動處理程序在KeyDown和KeyUp事件
  2. 或單獨的事件流爲Alt鍵狀態確認,我會找出交織在我的代碼

但是,當然,有這種行爲,更糟糕的是,沒有線索如何繼續瞭解它,是非常糟糕的。我會很感激任何想法!

(注:引用添加System.coreex,System.Reactive和System.Interactive)

using System; 
using System.Collections.Generic; 
using System.Linq; 
using System.Windows; 
using System.Windows.Input; 

namespace DownAndMoveTest 
{ 
    public partial class MainWindow : Window 
    { 
     public MainWindow() 
     { 
      InitializeComponent(); 
      (from mDown in this.GetLeftMouseDownObservable(). 
       Do(e => this.Title = "DOWN: " + e.EventArgs.GetPosition(this).ToString()) 
      let mDownP = mDown.EventArgs.GetPosition(this) 
      from mMove in this.GetMouseMoveObservable().TakeUntil(this.GetLeftMouseUpObservable()) 
      select new 
      { 
       D = mDownP, 
       M = mMove.EventArgs.GetPosition(this) 
      }).Subscribe(ps => 
      { 
       this.Title = String.Format(
        "Window MouseDown({0:G}, {1:G}), MouseMove({2:G}, {3:G})", 
        ps.D.X, ps.D.Y, 
        ps.M.X, ps.M.Y); 
      }); 
     } 
    } 
    public static partial class UIElementExtensions 
    { 
     public static IObservable<IEvent<MouseButtonEventArgs>> 
      GetLeftMouseDownObservable(this UIElement uiElement) 
     { 
      return Observable.FromEvent<MouseButtonEventHandler, MouseButtonEventArgs>(
       h => new MouseButtonEventHandler(h), 
       h => uiElement.MouseLeftButtonDown += h, 
       h => uiElement.MouseLeftButtonDown -= h); 
     } 

     public static IObservable<IEvent<MouseEventArgs>> 
      GetMouseMoveObservable(this UIElement uiElement) 
     { 
      return Observable.FromEvent<MouseEventHandler, MouseEventArgs>(
       h => new MouseEventHandler(h), 
       h => uiElement.MouseMove += h, 
       h => uiElement.MouseMove -= h); 
     } 

     public static IObservable<IEvent<MouseButtonEventArgs>> 
      GetLeftMouseUpObservable(this UIElement uiElement) 
     { 
      return Observable.FromEvent<MouseButtonEventHandler, MouseButtonEventArgs>(
       h => new MouseButtonEventHandler(h), 
       h => uiElement.MouseLeftButtonUp += h, 
       h => uiElement.MouseLeftButtonUp -= h); 
     } 
    } 
} 

及其XAML

<Window x:Class="DownAndMoveTest.MainWindow" 
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" 
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" 
    Title="MainWindow" Height="350" Width="525"> 
    <Grid> 
    </Grid> 
</Window> 

回答

1

您的應用程序有一個主菜單?按alt鍵可以對菜單欄進行對焦,再次按下alt鍵可以將焦點恢復到之前關注的任何位置。這將解釋您所看到的功能。 (它看起來不像一個Rx問題)

+0

我會看看那個,理查德。我沒有做任何事情來專門在應用程序中設置菜單(上面的XAML是整個事情),但是整個WPF「Command」基礎架構似乎是活躍的,可能會這樣做。snoop工具正在幫助我一點。 blois.us/snoop。 – 2010-11-28 14:19:57