ما هي أفضل طريقة لتنظيم رمز السحب والإفلات من LINQ إلى ANDERS؟

StackOverflow https://stackoverflow.com/questions/2574046

سؤال

أحاول التعامل مع تفاعل السحب والإفلات ، والذي يتضمن الماوس لأسفل ، وتحرك الماوس ، والماوس.

فيما يلي نسخة مبسطة لحلتي:

  • على الماوس لأسفل ، يخلق القطع الناقص ويضيفه إلى قماش
  • في تحرك الماوس ، تعيد وضع القطع الناقص لمتابعة الماوس
  • على الفأر ، يغير لون اللوحة القماشية بحيث يكون من الواضح أي واحد تقوم بسحبه.

    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, ، سوف يحدث مرتين.

ثانياً ، تم تحديد رد اتصال الماوس قبل رد الاتصال Mousemove. هذا يجعل من الصعب القراءة بعض الشيء.

ثالثًا ، يبدو أن الإشارة إلى القطع الناقص في مكان سخيف. إذا كان هناك اشتراكين ، فسيتم كتابة هذا المرجع المتغير بسرعة كبيرة. أنا متأكد من أنه يجب أن يكون هناك طريقة يمكننا الاستفادة من let الكلمة الرئيسية لتقديم متغير لتعبير LINQ الذي يعني أن مرجع القطع الناقص الصحيح متاح لكل من Mouse Move و Mouse Up Dontlers

كيف تكتب هذا الرمز؟

هل كانت مفيدة؟

المحلول

لتجنب الآثار الجانبية الفرعية ، يجب عليك نشر الملاحظة. أعتقد أن شيئًا كهذا سيكون على ما يرام:

        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();
    }
مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top