更新时间:2023-11-25 11:01:04
该序列永远不会完成,因为源(的MouseDown)永远不会完成(这是一个事件)。值得指出的是,一个的IObservable
不能打电话的的onComplete
用户超过一次,这是合同的组成部分( OnNext *(OnCompleted |的OnError)
)
The sequence never completes because the source (MouseDown) never completes (it is an event). It's worth pointing out that a IObservable
cannot call OnComplete
of a subscriber more than once, it's part of the contract (OnNext* (OnCompleted|OnError)?
).
要找出当 mouseMove.TakeUntil(mouseUp事件)
序列完成后,你需要挂接到调用的SelectMany
:
To find out when themouseMove.TakeUntil(mouseUp)
sequence completes, you'll need to hook into the call to SelectMany
:
public static IDisposable TrackDrag(this UIElement element,
Action<Rect> dragging, Action dragComplete)
{
var mouseDown = Observable.FromEvent(...);
var mouseMove = Observable.FromEvent(...);
var mouseUp = Observable.FromEvent(...);
return (from start in mouseDown
from currentPosition in mouseMove.TakeUntil(mouseUp)
.Do(_ => {}, () => dragComplete())
select new Rect(Math.Min(start.X, currentPosition.X),
Math.Min(start.Y, currentPosition.Y),
Math.Abs(start.X - currentPosition.X),
Math.Abs(start.Y - currentPosition.Y));
).Subscribe(dragging);
}
然后你可以使用它像这样:
Then you can use it like so:
element.TrackDrag(
rect => { },
() => {}
);
有关为清楚起见,这里是使用底层的扩展方法的LINQ EX pression:
For the interest of clarity, here is the LINQ expression using the underlying extension methods:
return mouseDown.SelectMany(start =>
{
return mouseMove
.TakeUntil(mouseUp)
.Do(_ => {}, () => dragComplete())
.Select(currentPosition => new Rect(...));
})
.Subscribe(dragging);
即,对于从MOUSEDOWN每个值的新的序列将被预订。当是的序列完成后,调用dragComplete()。
That is, for each value from mouseDown a new sequence will be subscribed to. When that sequence completes, call dragComplete().