Question

I'm learning MVVM design pattern so I'm trying to change some operation into Command.
Here's an example, MainWindow has a Canvas as the container, and the user can draw rectangle through dragging. So I write the code as below

protected override void OnMouseLeftButtonDown(MouseButtonEventArgs e)
{
    base.OnMouseLeftButtonDown(e);
    StartPoint = e.GetPosition(this);      
    shape = new Rectangle();
    shape.Fill = Brushes.Transparent;
    shape.Stroke = Brushes.Black;
    shape.StrokeThickness = 1;
    this.Children.Add(shape);
}

protected override void OnMouseMove(MouseButtonEventArgs e)
{
    Point endpoint = e.GetPosition(this);
    double left = Math.Min(endpoint.X, StartPoint.X);
    double top = Math.Min(endpoint.Y, StartPoint.Y);
    shape.Margin = new Thickness(left, top, 0, 0);
    shape.Width = Math.Abs(endpoint.X - StartPoint.X);
    shape.Height = Math.Abs(endpoint.Y - StartPoint.Y);
    shape.Stroke = Brushes.Black;
    shape.StrokeThickness = 2;
}

protected override void OnMouseLeave(MouseButtonEventArgs e)
{
    //end
}

Since maybe I wanna add Undo function so that the rectangle will disappear after Undo invoked, so I want to make these 3 steps into one command. How should I do this? Thanks.

Était-ce utile?

La solution

Microsoft's Expression Blend Behaviors does this. To implement and use your own behaviors you do not need Expression Blend, just the SDK which is available for download.

The way it works is you implement Behavior where T : DependencyObject. The class has two overrideable methods OnAttach() and OnDetach() which you wire and unwire to your events, and put the above logic inside the behavior. If you were to name your class DrawRectangleBehavior, then, all you need to do is this:

....
xmlns:i="http://schemas.microsoft.com/expression/2010/interactivity"
....

<Canvas>
    <i:Interaction.Behaviors>
        <myBlend:DrawRectangleBehavior />
    </i:Interaction.Behaviors>
</Canvas>

And the behavior (I did not test this)

using System;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Input;
using System.Windows.Interactivity;
using System.Windows.Media;
using System.Windows.Shapes;

namespace MyCompany.Common.Behaviors
{
    public class DrawRectangleBehavior : Behavior<Canvas>
    {
        Point StartPoint;
        Shape shape;

        protected override void OnAttached()
        {
            AssociatedObject.PreviewMouseLeftButtonDown += OnMouseLeftButtonDown;
            AssociatedObject.PreviewMouseMove += OnMouseMove;
            AssociatedObject.MouseLeave += OnMouseLeave;
        }

        protected override void OnDetaching()
        {
            AssociatedObject.PreviewMouseLeftButtonDown -= OnMouseLeftButtonDown;
        AssociatedObject.PreviewMouseMove -= OnMouseMove;
        AssociatedObject.MouseLeave -= OnMouseLeave;
        }


        protected void OnMouseLeftButtonDown(object o, MouseButtonEventArgs e)
        {
            StartPoint = e.GetPosition(AssociatedObject);
            shape = new Rectangle();
            shape.Fill = Brushes.Transparent;
            shape.Stroke = Brushes.Black;
            shape.StrokeThickness = 1;
            AssociatedObject.Children.Add(shape);
        }

        protected void OnMouseMove(object o, MouseEventArgs e)
        {
            Point endpoint = e.GetPosition(AssociatedObject);
            double left = Math.Min(endpoint.X, StartPoint.X);
            double top = Math.Min(endpoint.Y, StartPoint.Y);
            shape.Margin = new Thickness(left, top, 0, 0);
            shape.Width = Math.Abs(endpoint.X - StartPoint.X);
            shape.Height = Math.Abs(endpoint.Y - StartPoint.Y);
            shape.Stroke = Brushes.Black;
            shape.StrokeThickness = 2;
        }

        protected void OnMouseLeave(object o, MouseEventArgs e)
        {
            //end
        }

    }
}

And you have a reusable piece of code.

Please see the following tutorial WPF Tutorial | Blend Behaviors

And the following download link Expression Blend SDK

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top