奇怪的事件串扰:鼠标&键盘,WPF&接收?

时间:2010-11-26 23:31:25

标签: wpf events keyboard mouseevent system.reactive

我在VS 2010中编写了一个非常小的WPF + Rx程序,它有一些意想不到的行为 - 似乎在鼠标事件可观察量中拾取了alt-key事件。

的任何建议我都很感激
  1. 什么是特别错误的
  2. 关于如何进一步自我诊断的想法或工具[例如,是否有一些工具可以检测代码以跟踪和记录所有被解雇的事件,以便我能更清楚地看到发生了什么?]
  3. 如何理解行为 - 是“按设计”吗?我是否滥用WPF或Rx或两者兼而有之?
  4. 如何获得我宁愿拥有的行为,如下所述
  5. 首先,它正确地做的是从鼠标向下开始并以鼠标向上结束的火鼠移动观察者。特定的测试观察者我只是将正确的mouseDown + mouseUp坐标放在Window的TitleBar中(参见下面的代码+ 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. 在鼠标移动处理程序中明确检查alt键状态
    2. 或单独的keyDown和keyUp事件的事件流,我将在我的代码中找出交错
    3. 但是,当然,有这种行为,更糟糕的是,不知道如何继续理解它,真的很糟糕。我会很感激任何想法!

      (注意:添加对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 个答案:

答案 0 :(得分:1)

您的应用程序是否有主菜单?按alt键可以聚焦菜单栏,再次按alt可以将焦点返回到之前具有焦点的任何焦点。这可以解释您所看到的功能。 (它看起来不像Rx问题)