我有一个网格,我想移动鼠标。虽然我只是徘徊和移动鼠标我希望事件发生,但当我按下mousedown他们应该暂停开火。一旦我开火,他们就应该继续。
如果这听起来非常简单,那可能不是。过了一段时间我们提出了一个不太优雅的解决方案,但我想知道是否存在更好的东西。我不会用我们的黑客来影响你的方法。
所以初始代码不起作用
mouseMove.TakeUntil(mouseDown).Repeat()
向.SkipUntil(mouseUp)
左侧或右侧添加TakeUntil
基本上可以停止上述代码。
答案 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
可观察量通常被定义。