为什么这个双击检测代码不可靠



我试图通过一些简单的挑战来学习Rx,首先通过观察MouseUp事件来检测双击。我提出了以下解决方案(该代码可以通过创建WPF项目并添加Reactive Extensions NuGet包来编译):

using System;
using System.Reactive.Linq;
using System.Windows.Input;
namespace WpfApplication1 {
    public partial class MainWindow {
        public MainWindow() {
            InitializeComponent();
            var clickEvents = Observable
                .FromEventPattern<MouseButtonEventArgs>(this, "MouseLeftButtonUp");
            var intraClickInterval = TimeSpan.FromMilliseconds(500);
            var interClickInterval = TimeSpan.FromMilliseconds(1000);
            var doubleClicks = clickEvents
                .TimeInterval()
                .SkipWhile(t => t.Interval < interClickInterval)
                .FirstAsync(t => t.Interval < intraClickInterval)
                .Repeat();
            var doubleClickReady = doubleClicks
                .Delay(interClickInterval)
                .Subscribe(e => Console.WriteLine("Now accepting double click!"));
            doubleClicks.Subscribe(e => Console.WriteLine(e.Interval));
        }
    }
}

我见过的大多数解决方案不处理多次点击,所以想法是每次双击之间总是等待一定的间隔(interClickInterval),然后双击是下一个鼠标向上事件,其间隔小于intraClickInterval。我还添加了一条消息,在每次双击后interClickInterval结束后打印,以便我知道何时应该注册双击。

这似乎在一般情况下工作得很好,但似乎有时他们不注册,即使我看到"现在接受双击!"消息。这似乎发生特别是如果我点击之前的消息出现。是什么原因造成的呢?

编辑:我认为双击检测实际上是正确的,这是不正确的消息。基本上,它忽略双击之后的任何后续单击。我需要做一些像

这样的东西
  • 每次双击事件
  • 等待interClickInterval
  • 如果没有点击注册,显示"现在接受双点击!"

所以正如我所怀疑的那样,检测代码是正确的,这是消息计时错误。它没有考虑双击之后的任何后续点击;它总是在每次双击后1000毫秒打印消息。下面是ready消息的一个版本,它正确地等待从每次双击后最后一次单击开始的1000ms时间:

        var doubleClickReady = doubleClicks
            .SelectMany(clickEvents
                .Buffer(interClickInterval)
                .FirstAsync(b => b.Count == 0));
        doubleClickReady
            .Subscribe(e => Console.WriteLine("Now accepting double click!"));

相关内容

  • 没有找到相关文章

最新更新