【问题标题】:Handling both Click and Double Click using Reactive.NET RX使用 Reactive.NET RX 处理 Click 和 Double Click
【发布时间】: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 会同时触发单击和双击。

怎样才能让它按预期工作,这样当双击被触发时,单击就不会了。

【问题讨论】:

    标签: c# .net observable system.reactive


    【解决方案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 =&gt; xs.Buffer(() =&gt; xs.Throttle(TimeSpan.FromMilliseconds(350.0)))) 以防止多次订阅您的 observable 源。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-08-30
    相关资源
    最近更新 更多