使用RX可以降低鼠标移动事件的频率

时间:2013-01-31 19:05:54

标签: wpf events mouse system.reactive

我是RX的新手,但我觉得它应该能够为我想要解决的任务提供一个好的解决方案。经过相当多的搜索后,我仍然没有找到解决方案。

我有一个WPF应用程序,其中一个控件可以响应一些鼠标移动事件。我想减少事件的频率,以便处理程序的调用频率低于当前情况(当用户将鼠标移过控件时)。理想情况下,我想要的是设置和订阅观察者。观察者应观察鼠标移动事件,并在特定时间窗口过去后用最近的事件和参数调用客户端代码,比如说0.2秒。作为RX的新手,我首先用观察者替换了我原来的标准事件连接,如下所示:

var mouseMove = Observable.FromEventPattern<MouseEventArgs>(myControl, "MouseMove");

mouseMove.Subscribe(args => myControl_MouseMove(args.Sender, args.EventArgs)); 

这似乎工作正常。

然后我尝试修改观察者以获得我上面描述的行为。我尝试使用Throttle()调用和Sample()调用。这些并没有产生我预期(或渴望)的结果。实际上在某些情况下使用Throttle / TimeSpan调用的特定过载导致我的应用程序死机,但我仍然不理解。

这是我尝试过的一个例子:

var mouseMove = Observable.FromEventPattern<MouseEventArgs>(myControl, "MouseMove").Throttle(TimeSpan.FromSeconds(0.2));

mouseMove.Subscribe(args => myControl_MouseMove(args.Sender, args.EventArgs)); 

从阅读开始,Throttle似乎吞下事件,直到频率降到特定阈值以下(不是我预期的那样),而我相信Sample会定期对观察到的事件进行采样?我希望在给定的时间间隔内为客户端代码提供最新的事件。如果在该时间间隔内未记录任何事件,则不应调用客户端。

希望有人可以帮助RX新手。

哦,我还希望在控制生命周期内随时了解鼠标移动(降低频率)。

最高

1 个答案:

答案 0 :(得分:4)

我认为你与Sample走在正确的轨道上 - 具体来说,这对你没有做什么?

示例LINQPad代码段:

void Main()
{
    var window = new Window();
    window.Content = ctrl;
    window.Show();
    var mouseMove = Observable
        .FromEventPattern<MouseEventArgs>(window, "MouseMove")
        .Sample(TimeSpan.FromSeconds(0.2));
    var disp = mouseMove.Subscribe(args => myControl_MouseMove(args.Sender, args.EventArgs));     
    window.Closed += (o,e) => disp.Dispose();
}

ItemsControl ctrl = new ItemsControl();

// Define other methods and classes here
private void myControl_MouseMove(object sender, MouseEventArgs args)
{
    ctrl.Dispatcher.BeginInvoke((Action)(() => {ctrl.Items.Add(args.GetPosition(ctrl));}));
}