技术开发 频道

C#中使用命令模式实现Undo/Redo

  示例应用程序描述

  这个示范WPF绘制应用程序用来作为结合Undo/Redo操作的案例。该WPF应用程序示例支持四种操作:插入对象、删除对象、移动对象和调整对象的尺寸,它还有两种类型的几何对象:矩形和多边形。它使用画布作为包含这些几何对象的容器。

  现在,在此系列文章中,我们可以看到如何让这四个操作支持Undo/Redo。在第一部分,使用单个对象表示变化的方法实现。在第二部分,使用命令模式实现而在第三部分,使用备忘录模式实现。

  使用命令模式实现示例应用程序的Undo/Redo

  利用命令模式对示范应用程序Undo/Redo的实现将在以下步骤中讨论:

  步骤1

  在示范应用程序中有四种操作,它们是移动、调整尺寸、插入和删除。对象是矩形、椭圆,而容器是一个WPF画布。

  步骤2

  现在我们要为四种操作创建四个继承ICommand接口的命令类。

class MoveCommand : ICommand
    {
        
private Thickness _ChangeOfMargin;
        
private FrameworkElement _UiElement;

        
public MoveCommand(Thickness margin, FrameworkElement uiElement)
        {
            _ChangeOfMargin
= margin;
            _UiElement
= uiElement;
        }

        
#region ICommand Members

        
public void Execute()
        {
            _UiElement.Margin
= new Thickness(_UiElement.Margin.Left +
   _ChangeOfMargin.Left, _UiElement.Margin.Top
              
+ _ChangeOfMargin.Top, _UiElement.Margin.Right +
   _ChangeOfMargin.Right, _UiElement.Margin.Bottom
+
   _ChangeOfMargin.Bottom);
        }

        
public void UnExecute()
        {
            _UiElement.Margin
= new Thickness(_UiElement.Margin.Left -
   _ChangeOfMargin.Left, _UiElement.Margin.Top
-
             _ChangeOfMargin.Top, _UiElement.Margin.Right
-
   _ChangeOfMargin.Right, _UiElement.Margin.Bottom
-
   _ChangeOfMargin.Bottom);
        }

        
#endregion
    }

 

  由于移动对象仅改变了几何对象的边距,移动命令将包含边距的变化,几何对象的引用。在移动命令中,Execute方法通过增加边距变化改变几何对象UIelement,而Unexecute方法通过减去刚应用的变化来撤销操作。这样,它减掉了几何对象UIelement的边距变化。

class ResizeCommand : ICommand
    {
        
private Thickness _ChangeOfMargin;
        
private double _ChangeofWidth;
        
private double _Changeofheight;
        
private FrameworkElement _UiElement;

        
public ResizeCommand(Thickness margin, double width,
  
double height, FrameworkElement uiElement)
        {
            _ChangeOfMargin
= margin;
            _ChangeofWidth
= width;
            _Changeofheight
= height;
            _UiElement
= uiElement;
        }

        
#region ICommand Members

        
public void Execute()
        {
            _UiElement.Height
= _UiElement.Height + _Changeofheight;
            _UiElement.Width
= _UiElement.Width + _ChangeofWidth;
            _UiElement.Margin
= new Thickness
  (_UiElement.Margin.Left
+ _ChangeOfMargin.Left,
  _UiElement.Margin.Top
            
+ _ChangeOfMargin.Top, _UiElement.Margin.Right +
  _ChangeOfMargin.Right, _UiElement.Margin.Bottom
+
  _ChangeOfMargin.Bottom);
        }

        
public void UnExecute()
        {
            _UiElement.Height
= _UiElement.Height - _Changeofheight;
            _UiElement.Width
= _UiElement.Width - _ChangeofWidth;
            _UiElement.Margin
= new Thickness(_UiElement.Margin.Left -
  _ChangeOfMargin.Left, _UiElement.Margin.Top
-
            _ChangeOfMargin.Top, _UiElement.Margin.Right
-
  _ChangeOfMargin.Right, _UiElement.Margin.Bottom
-
  _ChangeOfMargin.Bottom);
        }

        
#endregion
    }
0
相关文章