奇怪事件串扰:鼠标和键盘、WPF和Rx?
我在VS2010中编写了一个非常小的WPF+Rx程序,它有一些意想不到的行为——似乎在鼠标事件观察中拾取alt键事件。如果您能给我任何建议,我将不胜感激 到底出了什么问题 关于如何自己进一步诊断的想法或工具[例如,是否有一些工具对代码进行检测,以跟踪和记录所有触发的事件,以便我能更清楚地看到发生了什么?] 如何理解行为——是设计的吗?我是否滥用WPF或Rx或两者? 如何获得我想要的行为,如下所述 首先,它正确的做法是从鼠标向下到鼠标向上发射鼠标移动观察者。我刚才提到的特定测试观察者将适当的mouseDown+mouseUp坐标放在窗口的标题栏中,请参见下面的代码+XAML 当鼠标按下并释放alt键时,这种奇怪的感觉开始了。这似乎立即阻止了mouseMove事件观察者。现在,如果我释放mouseButton,mouseMove事件观察程序将再次启动,并继续,直到我生成新的mouseDown或再次按下并释放alt。更进一步,如果我通过这个序列,也就是奇怪事件串扰:鼠标和键盘、WPF和Rx?,wpf,events,keyboard,mouseevent,system.reactive,Wpf,Events,Keyboard,Mouseevent,System.reactive,我在VS2010中编写了一个非常小的WPF+Rx程序,它有一些意想不到的行为——似乎在鼠标事件观察中拾取alt键事件。如果您能给我任何建议,我将不胜感激 到底出了什么问题 关于如何自己进一步诊断的想法或工具[例如,是否有一些工具对代码进行检测,以跟踪和记录所有触发的事件,以便我能更清楚地看到发生了什么?] 如何理解行为——是设计的吗?我是否滥用WPF或Rx或两者? 如何获得我想要的行为,如下所述 首先,它正确的做法是从鼠标向下到鼠标向上发射鼠标移动观察者。我刚才提到的特定测试观察者将适当的mou
mouseDown
mouseMove
alt-key down
alt-key up
mouseUp
alt-key down
alt-key up
然后,正常的
mouseDown
mouseMove
标题栏上的文字有一些奇怪的闪烁,告诉我还有其他无关的事件被跟踪并通过我的观察者lambda发送
除了alt键,我还没能用其他键使它失败,这加深了谜团
期望的行为可能是
在鼠标移动处理程序中显式检查alt键状态
或者为keyDown和keyUp事件分离事件流,我将在代码中找出交错
但是,可以肯定的是,有这种行为,更糟糕的是,不知道如何去理解它,真的很糟糕。如果有任何想法,我将不胜感激
注意:添加对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>
你的应用程序有主菜单吗?按alt键可聚焦菜单栏,再次按alt键可将焦点恢复到以前的焦点。这将解释您看到的功能。它看起来不像是Rx问题我来看看,Richard。我没有做任何事情专门在应用程序中添加菜单上面的XAML就是全部,但是整个WPF命令基础结构似乎都是活动的,这可能正在起作用。窥探工具对我有点帮助。blois.us/snoop。