如何编写鼠标拖动交互的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
- 有什么好的方法可以保存起点的信息?我对此感到有点笨拙。
- 我如何对结果进行分组,以便每个组合的鼠标拖动交互恰好有一个 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
坐标的记录。然后很容易根据每次移动过程中的位置生成一系列坐标增量。
我想使用 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
- 有什么好的方法可以保存起点的信息?我对此感到有点笨拙。
- 我如何对结果进行分组,以便每个组合的鼠标拖动交互恰好有一个 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
坐标的记录。然后很容易根据每次移动过程中的位置生成一系列坐标增量。