gpt4 book ai didi

.net - 构建此 Linq-to-Events 拖放代码的最佳方法是什么?

转载 作者:行者123 更新时间:2023-12-02 05:26:43 25 4
gpt4 key购买 nike

我正在尝试处理拖放交互,其中涉及鼠标按下、鼠标移动和鼠标向上。

这是我的解决方案的简化重现:

  • 按下鼠标时,创建一个椭圆并将其添加到 Canvas
  • 鼠标移动时,重新定位椭圆以跟随鼠标
  • 鼠标松开时,更改 Canvas 的颜色,以便清楚地看出您正在拖动哪一个。

    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();
}

关于.net - 构建此 Linq-to-Events 拖放代码的最佳方法是什么?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/2574046/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com