如何编写鼠标拖动交互的RX.Net个Observables?

How to compose RX.Net Observables for mouse dragging interaction?

我想使用 RX 启用鼠标拖动行为到绘图中的 select 个区域。 (Oxyplot)应该可以 select 一个地块中的多个区域,它们应该是 select 区域的实时更新。

到目前为止,我已经从事件中设置了三个可观察值:

var mouseDownObservable = Observable.FromEventPattern<OxyMouseDownEventArgs>(tmp, nameof(tmp.MouseDown))
            .Where(e => e.EventArgs.ChangedButton == OxyMouseButton.Left)
            .Where(e => e.EventArgs.IsControlDown == true);
var mouseMoveObservable = Observable.FromEventPattern<OxyMouseEventArgs>(tmp, nameof(tmp.MouseMove));
var mouseUpObservable = Observable.FromEventPattern<OxyMouseEventArgs>(tmp, nameof(tmp.MouseUp));

我是 RX 的新手,所以我的第一次尝试是:

var result = mouseDownObservable
                .Select(m => m.EventArgs.Position)
                .Merge(mouseMoveObservable
                .SkipUntil(mouseDownObservable.Select(e => e.EventArgs.Position).Do(e1 =>
                {
                    // .. create annotation in plot
                }))
                .TakeUntil(mouseUpObservable)
                .Select(m => m.EventArgs.Position)
                .Repeat());
                .CombineLatest(mouseDownObservable.Select(e => e.EventArgs.Position),
                        (endPoint, startPoint) => new List<ScreenPoint>() { endPoint, startPoint })
                .Do(e =>
                {
                    // .. update actual annotation to current endPoint
                })
                .Subscribe();

我不知道如何保存状态(mouseDown 的起始点)所以我选择使用 CombineLatest。

第一个select一个区域效果很好。如果我想 select 另一个区域我得到正确的起点 (d1) 但终点仍然是 (r) 的最后一个元素。 Marble Diagram

  1. 有什么好的方法可以保存起点的信息?我对此感到有点笨拙。
  2. 我如何对结果进行分组,以便每个组合的鼠标拖动交互恰好有一个 mouseDragObservable?

我觉得你有点想多了。

这是您需要的查询:

var deltas =
    from down in mouseDownObservable
    from move in mouseMoveObservable.TakeUntil(mouseUpObservable)
    select new
    {
        X = move.EventArgs.Position.X - down.EventArgs.Position.X,
        Y = move.EventArgs.Position.Y - down.EventArgs.Position.Y
    };

所以这只是等待鼠标按下,然后记录之后发生的所有移动,直到鼠标松开。所以,基本上就是一个拖动操作。

因为第一部分是 from down in mouseDownObservable 你有鼠标按下时 X/Y 坐标的记录。然后很容易根据每次移动过程中的位置生成一系列坐标增量。