Почему этот код обнаружения двойного щелчка ненадежен?
Я пытаюсь изучить Rx с помощью некоторых простых задач, сначала обнаруживая двойные щелчки, наблюдая только за событиями MouseUp. Я придумал следующее решение (этот код компилируется путем создания проекта WPF и добавления пакета реактивных расширений 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) между каждым двойным щелчком, а затем двойной щелчок является следующим событием мыши вверх у него интервал меньше, чем у интракликинтервала. Я также добавил сообщение, которое печатается после того, как interClickInterval истекает после каждого двойного щелчка, чтобы я знал, когда должны регистрироваться двойные щелчки.
Это, кажется, работает хорошо в целом, но кажется, что иногда они не регистрируются, хотя я вижу " теперь принимаю двойной щелчок!" сообщение. Это, кажется, происходит особенно, если я нажимаю непосредственно перед появлением сообщения. Что может быть причиной вот это?
EDIT: я думаю, что обнаружение двойного щелчка на самом деле правильно, это сообщение, которое не является. в основном, он игнорирует любой последующий щелчок после двойного щелчка. Мне нужно было бы сделать что-то вроде
- для каждого события двойного щелчка
- дождитесь интеркликинтервала
- если с тех пор не было зарегистрировано ни одного щелчка, выведите на экран сообщение " Теперь принимаю двойной щелк!"
Но я не уверен, как этого добиться...
1 ответ:
Итак, как я и подозревал, код обнаружения верен,это сообщение, которое было рассчитано неправильно. Он не учитывал никаких последующих кликов после двойного щелчка; он просто всегда печатал свое сообщение 1000 мс после каждого двойного щелчка. Вот версия готового сообщения, которое корректно ожидает 1000 мс, прошедших с момента последнего щелчка после каждого двойного щелчка:
var doubleClickReady = doubleClicks .SelectMany(clickEvents .Buffer(interClickInterval) .FirstAsync(b => b.Count == 0)); doubleClickReady .Subscribe(e => Console.WriteLine("Now accepting double click!"));