我有一个带有 MouseWheel 事件的 WPF 应用程序。本次活动的操作相当繁重。因此,我只想在用户停止滚动时执行此事件(即:如果他在给定的时间内没有滚动)。
在 JS 中,这很容易,如果在执行之前发生了另一个滚动,我可以将 var 放入setTimout
一个 var 中,然后在该 var 上执行一个(例如,这对于自动完成非常有用)。clearTimeout
setTimeout
我怎样才能做到这一点c#
?
我有一个带有 MouseWheel 事件的 WPF 应用程序。本次活动的操作相当繁重。因此,我只想在用户停止滚动时执行此事件(即:如果他在给定的时间内没有滚动)。
在 JS 中,这很容易,如果在执行之前发生了另一个滚动,我可以将 var 放入setTimout
一个 var 中,然后在该 var 上执行一个(例如,这对于自动完成非常有用)。clearTimeout
setTimeout
我怎样才能做到这一点c#
?
System.Reactive.Windows.Threading
使用 Microsoft 的 Reactive Framework (aka Rx) - NuGet (for WPF) 并添加非常容易using System.Reactive.Linq;
- 然后你可以这样做:
IObservable<EventPattern<MouseWheelEventArgs>> query =
Observable
.FromEventPattern<MouseWheelEventHandler, MouseWheelEventArgs>(
h => ui.MouseWheel += h, h => ui.MouseWheel -= h)
.Throttle(TimeSpan.FromMilliseconds(250.0))
.ObserveOnDispatcher();
IDisposable subscription =
query
.Subscribe(x =>
{
/* run expensive code */
});
文档是这样说的Throttle
:
忽略来自可观察序列的值,这些值在指定源和到期时间的到期时间之前后跟另一个值。
以下内容可能适合您的需求
public class perRxTickBuffer<T>
{
private readonly Subject<T> _innerSubject = new Subject<T>();
public perRxTickBuffer(TimeSpan? interval = null)
{
if (interval == null)
{
interval = TimeSpan.FromSeconds(1);
}
Output = _innerSubject.Sample(interval.Value);
}
public void Tick(T item)
{
_innerSubject.OnNext(item);
}
public IObservable<T> Output { get; }
}
创建一个实例,其中 T 是您的事件的事件参数类型。
设置一个适当的时间跨度值 - 对于您的情况可能是 1/4 秒。
只需Tick()
从您的事件处理程序中调用,然后订阅Output
observable 以获取受监管的“事件”流。