#c# #observable #reactive-programming #system.reactive #rx.net
#c# #наблюдаемые #реактивное программирование #система.реактивная #rx.net
Вопрос:
Я хочу использовать RX, чтобы включить режим перетаскивания мыши для выделения областей на графике. (Оксиплот) Должна быть возможность выбрать несколько областей на графике, и они должны быть текущим обновлением выбранной области.
До сих пор я настроил три наблюдаемых объекта из событий:
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();
Я не знал, как сохранить состояние (начальная точка наведения курсора мыши), поэтому я решил использовать combineLatest.
Сначала я выбираю область, которая работает довольно хорошо. Если я хочу выбрать другую область, я получаю правильную начальную точку (d1), но конечная точка по-прежнему является последним элементом (r). Диаграмма из мрамора
- Каков хороший подход к сохранению информации о начальной точке? Я чувствую себя немного неуклюжей из-за этого.
- Как я могу сгруппировать результат так, чтобы было ровно одно mouseDragObservable для каждого комбинированного взаимодействия перетаскивания мыши?
Ответ №1:
Я думаю, ты немного переусердствовал.
Вот запрос, который вам нужен:
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
координат / во время нажатия мыши. Затем очень легко создать серию дельт координат на основе положения во время каждого перемещения.
Комментарии:
1. Спасибо за ваш быстрый ответ, это было очень полезно. Да, я тоже думаю, что я слишком много думал об этом. 🙂