Estoy tratando de manejar un arrastre & soltar la interacción, que implica el mouse hacia abajo, el movimiento del mouse y el mouse hacia arriba.¿Cuál es la mejor manera de estructurar este código de arrastrar y soltar de Linq-to-Events?
Aquí es una repro simplificada de mi solución que:
- el ratón hacia abajo, crea una elipse y lo añade a un lienzo
- al mover el ratón, reposiciona la elipse para seguir al ratón
en el mouse hacia arriba, cambia el color del lienzo para que sea obvio cuál arrastras.
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); });
el XAML es simplemente
<Canvas x:Name="canvas"/>
Hay algunas cosas que no me gustan de este código, y necesito ayuda refactorización :)
En primer lugar: las devoluciones de llamada mousedown y mouseup se especifican como efectos secundarios. Si se hacen dos suscripciones a q
, sucederán dos veces.
En segundo lugar, la devolución de llamada del mouse se especifica antes de la devolución de llamada del mousemove. Esto hace que sea un poco difícil de leer.
En tercer lugar, la referencia a la elipse parece estar en un lugar tonto. Si hay dos suscripciones, esa referencia de variable se sobrescribirá rápidamente. Estoy seguro de que debería haber alguna forma de aprovechar la palabra clave let
para introducir una variable a la expresión linq que significará que la referencia de elipse correcta está disponible para los manejadores de movimiento y ratón del mouse
¿Cómo escribirías? este código?
Me gusta cómo se lee. Dónde (lo hizo)/(puedo) leer más acerca de 'Suscribirse' y' Conectar' –
@ rob-fonseca-ensor Reactive Extensions Forum en MSDN http://social.msdn.microsoft.com/Forums/en-US/ rx/threads es el único lugar por ahora ... Necesitamos ver más preguntas sobre SO. –