什么是最好的方式结构,这个皇宫-对-事拖拉的代码?
-
24-09-2019 - |
题
我试图处理一个拖拉的互动,其中涉及老鼠下,老鼠移动和鼠标。
这里是一个简化的重现我的解决方案:
- 在鼠下,创建一个椭圆,并将它添加到画布
- 在老鼠移动,重新定位椭圆遵循鼠
在鼠,改变颜色的画布所以,这是显而易见的是哪一个你拖动。
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回指定 之前 该鼠标移回调。这使得它有点难于阅读。
第三,参考椭圆似乎是在一个愚蠢的地方。如果有两个订阅,该变量的基准将得到复盖相当迅速。我敢肯定,应该有一些办法,我们可以利用 let
关键字来介绍一个变量来皇宫的表达,这将意味着正确的椭圆参考是提供给老鼠移动和老鼠了处理程序
你会怎么写这个代码?
解决方案
为了避免subscrition的副作用,应发布观察。我认为这样的事情将是确定:
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();
}
不隶属于 StackOverflow