简体   繁体   English

为什么此双击检测代码不可靠?

[英]Why is this double-click detection code unreliable?

I'm trying to learn Rx through some simple challenges, first by detecting double-clicks by watching only MouseUp events. 我试图通过一些简单的挑战来学习Rx,首先通过仅观看MouseUp事件来检测双击。 I came up with the following solution (this code is compilable by creating a WPF project and adding the Reactive Extensions NuGet package): 我提出了以下解决方案(可通过创建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));
        }
    }
}

Most solutions I've seen don't deal with multiple clicks, so the idea is to always wait for a certain interval (interClickInterval) between each double-click, and then a double-click is the next mouse up event that has an interval smaller than the intraClickInterval. 我见过的大多数解决方案都不会处理多次单击,因此,想法是始终在每次双击之间等待一定的间隔(interClickInterval),然后双击是下一个具有间隔的鼠标上移事件小于intraClickInterval。 I've also added a message that gets printed after the interClickInterval elapses following each double-click so that I know when double-clicks are supposed to register. 我还添加了一条消息,该消息在每次双击后经过interClickInterval之后都会打印出来,以便我知道何时应该注册双击。

This seems to work well in general, but it seems that sometimes they do not register even though I see the "Now accepting double-click!" 总体来说,这似乎效果很好,但即使我看到“现在接受双击!”,有时他们也没有注册。 message. 信息。 This seems to happen particularly if I click just before the message appears. 尤其是如果我在出现消息之前单击,这似乎会发生。 What could be causing this? 是什么原因造成的?

EDIT: I think the double-click detection is actually correct, it's the message that isn't. 编辑:我认为双击检测实际上是正确的,这是不正确的消息。 Basically, it ignores any subsequent click after a double-click. 基本上,它会忽略双击后的任何后续单击。 I'd need to do something like 我需要做类似的事情

  • for each double click event 对于每个双击事件
  • wait for the interClickInterval 等待interClickInterval
  • if no click was registered since, display "Now accepting double click!" 如果此后未注册任何点击,则显示“现在接受双击!”。

But I'm not sure how to achieve that... 但我不确定如何实现...

So as I suspected, the detection code is correct, it's the message that was timed incorrectly. 因此,正如我怀疑的那样,检测代码是正确的,这是消息的计时不正确。 It didn't take into account any subsequent clicks after a double-click; 双击后未考虑任何后续点击; it just always printed its message 1000ms after each double-click. 每次双击后始终仅在1000毫秒内打印其消息。 Here's a version of the ready message that correctly waits for 1000ms to have elapsed since the last click after each double-click: 这是就绪消息的版本,该消息正确地等待每次双击后的最后一次单击以来已经经过1000毫秒:

        var doubleClickReady = doubleClicks
            .SelectMany(clickEvents
                .Buffer(interClickInterval)
                .FirstAsync(b => b.Count == 0));

        doubleClickReady
            .Subscribe(e => Console.WriteLine("Now accepting double click!"));

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM