Rob*_*sor 5 .net drag-and-drop system.reactive c#-4.0
我正在尝试处理拖放交互,包括鼠标按下,鼠标移动和鼠标移动.
以下是我的解决方案的简化版本:
在鼠标向上时,更改画布的颜色,以便明显拖动哪一个.
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);
});
Run Code Online (Sandbox Code Playgroud)XAML很简单
<Canvas x:Name="canvas"/>
Run Code Online (Sandbox Code Playgroud)
有一些我不喜欢这个代码的东西,我需要帮助重构它:)
首先:mousedown和mouseup回调被指定为副作用.如果进行了两次订阅q,则会发生两次.
其次,在mousemove回调之前指定mouseup 回调.这使得它有点难以阅读.
第三,对椭圆的引用似乎是在一个愚蠢的地方.如果有两个订阅,则该变量引用将很快被覆盖.我确信应该有一些方法可以利用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();
}
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
425 次 |
| 最近记录: |