当鼠标按键按下时,我该如何防止mousemove事件的触发?

4
我有一个网格,我想在上面移动鼠标。当我只是悬停并移动鼠标时,我希望事件会触发,但是当我按下mousedown时,它们应该暂停触发。一旦我松开mouseup,它们就应该继续。
如果这听起来非常简单,那可能并不是。经过一段时间的思考后,我们想出了一个不太优雅的解决方案,但我想知道是否存在更好的方法。我不会用我们的hack影响您的方法。
所以初始代码是不能正常工作的。
mouseMove.TakeUntil(mouseDown).Repeat()

TakeUntil中添加.SkipUntil(mouseUp),基本上会使上面的代码完全停止工作。


我会到那里的...我猜你也不会喜欢我的最后一个问题。 - Valentin Kuzub
4个回答

2
这样怎么样:
bool mouseIsDown = false;
Observable.Merge(
    mouseDown.Select(_ => true),
    mouseUp.Select(_ => false)
).Subscribe(x => mouseIsDown = x);

mouseMove.Where(_ => !mouseIsDown);

技术上正确的答案涉及到Window操作符,但是这个方法同样有效且更易理解(对我来说也更容易写)


这实际上与 OP 所问的相反。你只需要在 Where 中反转条件。无论如何加 1。 - Ilian

0

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

// 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);

0

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

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( .... );

OR

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(....);

0

这个有效:

        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
否则,mouseDownmouseMove可观察对象将正常定义。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接