1

我正在学习 MVVM 设计模式,所以我试图将一些操作更改为命令。
这里举个例子,MainWindow有一个Canvas作为容器,用户可以通过拖拽来绘制矩形。所以我写代码如下

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
}

因为也许我想添加 Undo 功能,以便在 Undo 调用后矩形会消失,所以我想将这 3 个步骤变成一个命令。我该怎么做?谢谢。

4

1 回答 1

1

Microsoft 的 Expression Blend Behaviors 就是这样做的。要实现和使用您自己的行为,您不需要 Expression Blend,只需要可下载的 SDK。

它的工作方式是你实现 Behavior where T : DependencyObject。该类有两个可覆盖的方法 OnAttach() 和 OnDetach(),您可以将它们连接和取消连接到您的事件,并将上述逻辑放入行为中。如果你要命名你的类 DrawRectangleBehavior,那么你需要做的就是:

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

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

和行为(我没有测试这个)

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
        }

    }
}

你有一段可重用的代码。

请看以下教程WPF 教程 | 混合行为

以及下面的下载链接Expression Blend SDK

于 2012-11-20T14:28:21.373 回答