我是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 似乎吞噬事件,直到频率降至特定阈值以下(不完全符合我的预期),而我相信样本会定期对观察到的事件进行采样?我希望在给定的时间间隔内为客户端代码提供最新事件。如果该间隔内未记录任何事件,则不应调用客户端。
希望有人可以帮助RX新手。
哦,我还希望在控件的生命周期内随时了解(降低频率)鼠标移动。
麦克斯
我认为您在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));}));
}