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

时间:2011-09-20 22:38:05

标签: c# .net silverlight system.reactive

我有一个网格,我想移动鼠标。虽然我只是徘徊和移动鼠标我希望事件发生,但当我按下mousedown他们应该暂停开火。一旦我开火,他们就应该继续。

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

所以初始代码不起作用

mouseMove.TakeUntil(mouseDown).Repeat()

.SkipUntil(mouseUp)左侧或右侧添加TakeUntil基本上可以停止上述代码。

4 个答案:

答案 0 :(得分:2)

这个怎么样:

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

mouseMove.Where(_ => !mouseIsDown);

技术上正确的答案涉及Window操作符,但是这样很容易理解(并且我更容易编写)

答案 1 :(得分: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);

答案 2 :(得分:0)

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

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

答案 3 :(得分:0)

这有效:

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

在没有实际需要手动执行鼠标操作的情况下启动observable所需的唯一技巧是:

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

请注意StartWith

否则mouseDown&amp; mouseMove可观察量通常被定义。