我正在尝试处理拖放交互,其中涉及鼠标向下、鼠标移动和鼠标向上。
这是我的解决方案的简化复制:
- 在鼠标按下时,创建一个椭圆并将其添加到画布
- 在鼠标移动时,重新定位椭圆以跟随鼠标
在鼠标向上时,更改画布的颜色,以便您拖动哪个画布一目了然。
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 表达式引入一个变量,这意味着鼠标移动和鼠标向上处理程序都可以使用正确的椭圆引用
你会怎么写这段代码?