如何在按下鼠标按钮时阻止鼠标移动事件
本文关键字:鼠标 移动 事件 按钮 | 更新日期: 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可观察性是正常定义的。