Я пытаюсь обработать перетаскивание, которое включает в себя мышь вниз, движение мыши и мышь вверх.
Вот упрощенное воспроизведение моего решения, которое:
- при наведении мыши, создает эллипс и добавляет его на холст
- при перемещении мыши перемещает эллипс, следуя за мышью
при наведении мыши, изменяет цвет холста так, чтобы было очевидно, какой из них вы перетаскиваете.
var mouseDown = Observable.FromEvent<MouseButtonEventArgs>(canvas, "MouseLeftButtonDown");
var mouseUp = Observable.FromEvent<MouseButtonEventArgs>(canvas, "MouseLeftButtonUp");
var mouseMove = Observable.FromEvent<MouseEventArgs>(canvas, "MouseMove");
Ellipse ellipse = null;
var q = from start in mouseDown.Do(x =>
{
// handle mousedown by creating a red ellipse,
// adding it to the canvas at the right position
ellipse = new Ellipse() { Width = 10, Height = 10, Fill = Brushes.Red };
Point position = x.EventArgs.GetPosition(canvas);
Canvas.SetLeft(ellipse, position.X);
Canvas.SetTop(ellipse, position.Y);
canvas.Children.Add(ellipse);
})
from delta in mouseMove.Until(mouseUp.Do(x =>
{
// handle mouse up by making the ellipse green
ellipse.Fill = Brushes.Green;
}))
select delta;
q.Subscribe(x =>
{
// handle mouse move by repositioning ellipse
Point position = x.EventArgs.GetPosition(canvas);
Canvas.SetLeft(ellipse, position.X);
Canvas.SetTop(ellipse, position.Y);
});
XAML - это просто
<Canvas x:Name="canvas"/>
Есть несколько вещей, которые мне не нравятся в этом коде, и мне нужна помощь в его рефакторинге:)
Прежде всего: обратные вызовы mousedown и mouseup указываются как побочные эффекты. Если две подписки сделаны на q
, они произойдут дважды.
Во-вторых, обратный вызов mouseup указывается до обратного вызова mousemove. Это делает его немного трудным для чтения.
В-третьих, ссылка на эллипс, кажется, находится в глупом месте. Если есть две подписки, эта ссылка на переменную будет перезаписана довольно быстро. Я уверен, что должен быть какой-то способ, которым мы можем использовать ключевое слово let
, чтобы ввести переменную в выражение linq, что будет означать, что правильная ссылка на эллипс доступна как для обработчиков перемещения мыши, так и для мыши вверх * *
Как бы вы написали этот код?