如何在按下鼠标按钮时阻止鼠标移动事件

本文关键字:鼠标 移动 事件 按钮 | 更新日期: 2023-09-27 18:09:05

我有一个网格,我想把鼠标移到上面。当我只是悬停和移动鼠标时,我希望事件启动,但当我按下鼠标时,它们应该暂停启动。一旦我启动鼠标,他们应该继续。

如果这听起来非常简单,那可能不是。过了一段时间,我们想出了一个不太优雅的解决方案,但我想知道是否存在更好的解决方案。我不会用我们的黑客攻击来影响你的方法。

所以不起作用的初始代码

mouseMove.TakeUntil(mouseDown).Repeat()

.SkipUntil(mouseUp)向左或向右添加到TakeUntil基本上停止了上述代码的工作。

如何在按下鼠标按钮时阻止鼠标移动事件

这个怎么样:

bool mouseIsDown = false;
Observable.Merge(
    mouseDown.Select(_ => true),
    mouseUp.Select(_ => false)
).Subscribe(x => mouseIsDown = x);
mouseMove.Where(_ => !mouseIsDown);

从技术上讲,正确的答案涉及Window运算符,但这同样好,更容易找到(对我来说也更容易编写(

这可能是一个可行的解决方案

// create the observables
IObservable<Point> mouseMove = Observable.FromEventPattern<MouseEventArgs>(this, "MouseDown")
    .Select(e=>e.EventArgs.GetPosition(this));
IObservable<bool> mouseDown = Observable.FromEventPattern(this, "MouseDown").Select(_ => false);
IObservable<bool> mouseUp = Observable.FromEventPattern(this, "MouseUp").Select(_ => true);
var merged = mouseUp.Merge(mouseDown).StartWith(true);
// sends the moves with the current state of the mouse button
var all = mouseMove.CombineLatest(merged, (move, take) => new {Take = take, Move = move});
// the result is all the points from mouse move where the mouse button isn't pressed
var result = all.Where(t => t.Take).Select(t => t.Move);

以下是两种可能的解决方案

var beh = new BehaviorSubject<bool>(true);
mousedown.Select(_ => false).Subscribe(beh);
mouseup.Select(_ => true).Subscribe(beh);
mousemove.SelectMany(e =>
{
     return mousemove.TakeUntil(beh.Where(b => !b));
}).Subscribe( .... );

var du = mousedown.Select(_ => false).Merge(mouseup.Select(_ => true)).Merge(Observable.Return(true));
mousemove.CombineLatest(du, (ev, b) => new Tuple<MouseEventArgs, bool>(ev.EventArgs, b))
 .Where(t => t.Item2)
 .Select(t => t.Item1)
 .Subscribe(....);

这是有效的:

        var mouseMoveWhileUpOnly =
            mouseUp
                .Select(mu =>
                    mouseMove
                        .TakeUntil(mouseDown))
                .Switch();

要想在不需要手动鼠标的情况下开始观察,你需要做的唯一技巧是:

        var mouseUp = Observable
            .FromEventPattern<MouseButtonEventHandler, MouseButtonEventArgs>(
                h => this.MouseLeftButtonUp += h,
                h => this.MouseLeftButtonUp -= h)
            .Select(ep => Unit.Default)
            .StartWith(Unit.Default);

注意StartWith

否则mouseDown&CCD_ 5可观察性是正常定义的。