Я пытаюсь обработать взаимодействие перетаскивания, которое включает мышь вниз, перемещение мыши и мышь.
Вот упрощенная репродукция моего решения что:
на мыши, изменяет цвет холста так, чтобы это было очевидно, какой Вы перетаскиваете.
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 выражению, которое будет означать корректную ссылку эллипса, доступно и перемещению мыши и мыши обработчики
Как Вы написали бы этот код?
Чтобы избежать побочных эффектов подписки, вам следует опубликовать наблюдаемую. Я думаю, что это будет нормально:
public MainWindow()
{
InitializeComponent();
var mouseDown = Observable
.FromEvent<MouseButtonEventArgs>(this, "MouseLeftButtonDown");
var mouseUp = Observable
.FromEvent<MouseButtonEventArgs>(this, "MouseLeftButtonUp");
var mouseMove = Observable
.FromEvent<MouseEventArgs>(this, "MouseMove");
var ellipses = mouseDown
.Select(args => new {
a = args,
el = new Ellipse
{
Width = 10, Height = 10, Fill = Brushes.Red
}})
.Publish();
ellipses
.Subscribe(elargs =>
{
var position = elargs.a.EventArgs.GetPosition(canvas);
Canvas.SetLeft(elargs.el, position.X);
Canvas.SetTop(elargs.el, position.Y);
canvas.Children.Add(elargs.el);
});
var elmove = from elargs in ellipses
from mm in mouseMove.TakeUntil(mouseUp)
select new { a = mm, el = elargs.el };
elmove.
Subscribe(elargs =>
{
var position = elargs.a.EventArgs.GetPosition(canvas);
Canvas.SetLeft(elargs.el, position.X);
Canvas.SetTop(elargs.el, position.Y);
});
var elmup = from elargs in ellipses
from mup in mouseUp
select elargs.el;
elmup.Subscribe(el => el.Fill = Brushes.Green);
ellipses.Connect();
}