使用 Reactive.NET RX 处理 Click 和 Double Click
Posted
技术标签:
【中文标题】使用 Reactive.NET RX 处理 Click 和 Double Click【英文标题】:Handling both Click and Double Click using Reactive.NET RX 【发布时间】:2021-11-06 04:07:45 【问题描述】:我在 .NET 中有一个 WPF 按钮,我希望分别处理单击和双击事件。我目前已经使用超时/延迟来完成这项工作,它可以工作,但它很难看。我正在尝试找到一种使用 System.Reactive .NET 扩展的巧妙方法
Observables 是从我传递按钮的工厂方法创建的,我使用 FromEventPattern(button, "click") 方法。例如:
public IObservable<EventPattern<RoutedEventArgs>> SingleClickTestObservable(Button button)
return Observable.FromEventPattern<RoutedEventArgs>(button, "Click");
public IObservable<EventPattern<RoutedEventArgs>> DoubleClickTestObservable(Button button)
return Observable.FromEventPattern<RoutedEventArgs>(button, "DoubleClick");
问题是当我订阅这些 Observables 时,SingleClick 会同时触发单击和双击。
怎样才能让它按预期工作,这样当双击被触发时,单击就不会了。
【问题讨论】:
【参考方案1】:我想出的解决方案是绑定到两个示例中的点击事件,并将事件放入一个 350 毫秒的缓冲区中。然后根据 350ms 时间段内发生的事件数进行过滤。
对于单击事件,我们希望缓冲区中有 1 个单击事件,而对于双击事件,我们希望恰好有 2 个:
public IObservable<EventPattern<RoutedEventArgs>> DoubleClickTestObservable(Button button)
var observable = Observable.FromEventPattern<RoutedEventArgs>(button, "Click");
var bufferedObservable = observable.Buffer(observable.Throttle(TimeSpan.FromMilliseconds(350)))
.Select(list => new list.Count, list )
.Where(result => result.Count == 2)
.Select(x => x.list.Last());
return bufferedObservable;
public IObservable<EventPattern<RoutedEventArgs>> SingleClickTestObservable(Button button)
var observable = Observable.FromEventPattern<RoutedEventArgs>(button, "Click");
var bufferedObservable = observable.Buffer(observable.Throttle(TimeSpan.FromMilliseconds(350)))
.Select(list => new list.Count, list )
.Where(result => result.Count == 1)
.Select(x => x.list.Single());
return bufferedObservable;
用法:
var button = GetMyButton();
var singleClickSub = DoubleClickTestObservable(button)
.Subscribe(pattern => _logger.Debug("got double click"); );
var doubleClickSub = SingleClickTestObservable(button)
.Subscribe(pattern => _logger.Debug("got single click"); );
注意:_logger是我的一个自定义类,替换为alert,或者其他输出方式进行测试。
【讨论】:
我建议添加.Publish(xs => xs.Buffer(() => xs.Throttle(TimeSpan.FromMilliseconds(350.0))))
以防止多次订阅您的 observable 源。以上是关于使用 Reactive.NET RX 处理 Click 和 Double Click的主要内容,如果未能解决你的问题,请参考以下文章
处理 RX 中的 response.body == null