为什么这个双击检测代码不可靠?
我试图通过一些简单的挑战来学习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(this, "MouseLeftButtonUp"); var intraClickInterval = TimeSpan.FromMilliseconds(500); var interClickInterval = TimeSpan.FromMilliseconds(1000); var doubleClicks = clickEvents .TimeInterval() .SkipWhile(t => t.Interval t.Interval Console.WriteLine("Now accepting double click!")); doubleClicks.Subscribe(e => Console.WriteLine(e.Interval)); } } }
我见过的大多数解决方案都没有处理多次点击,因此我们的想法是在每次双击之间始终等待一定的间隔(interClickInterval),然后双击是下一个具有间隔的鼠标向上事件小于intraClickInterval。 我还添加了一条消息,在每次双击后经过interClickInterval后打印,以便我知道双击应该注册的时间。
这似乎总体上运作良好,但有时他们似乎没有注册,即使我看到“现在接受双击!” 信息。 如果我在消息出现之前单击,这似乎就会发生。 可能是什么导致了这个?
编辑:我认为双击检测实际上是正确的,它是不是的消息。 基本上,它会在双击后忽略任何后续点击。 我需要做点什么
- 对于每次双击事件
- 等待interClickInterval
- 如果之后没有注册点击,则显示“现在接受双击!”
但我不确定如何实现这一目标……
因此,我怀疑,检测代码是正确的,这是错误定时的消息。 双击后没有考虑任何后续点击; 它只是在每次双击后始终打印1000ms的消息。 这是一个就绪消息的版本,它在每次双击后正确等待自上次单击后经过1000毫秒:
var doubleClickReady = doubleClicks .SelectMany(clickEvents .Buffer(interClickInterval) .FirstAsync(b => b.Count == 0)); doubleClickReady .Subscribe(e => Console.WriteLine("Now accepting double click!"));