技术开发 频道

C#中使用备忘录模式实现Undo/Redo

  步骤6

  在你应用程序每次操作后,调用UndoRedo类的SetStateForUndoRedo()方法来使Undo Redo操作可用。

  示例应用程序描述

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

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

  使用备忘录模式实现示例应用程序的Undo/Redo

  步骤1

  这里的容器是包含Uielement对象的画布,而在不同操作期间,容器没有属性发生改变。

  步骤2

  现在,我们将使下面的memento类包含Uielement对象作为画布的状态。

Collapse  Copy Code
  
public class Memento
    {
        
private List<UIElement> _ContainerState;

        
public List<UIElement> ContainerState
        {
            
get { return _ContainerState; }
        }
        
public Memento(List<UIElement> containerState)
        {
            
this._ContainerState = containerState;
        }
    }

  现在这个备忘录代表了画布的状态。

  步骤3

  接下来的MementoOriginator利用深度拷贝画布的对象创建其备忘录并将备忘录设置给画布。

Collapse  Copy Code
  
public class MementoOriginator
    {
        
private Canvas _Container;

        
public MementoOriginator(Canvas container)
        {
            _Container
= container;
        }

        
public Memento getMemento()
        {
            List
<UIElement> _ContainerState = new List<UIElement>();

            
foreach (UIElement item in _Container.Children)
            {
                
if (!(item is Thumb))
                {
                    UIElement newItem
= DeepClone(item);
                    _ContainerState.Add(newItem);
                }
            }

            
return new Memento(_ContainerState);

        }

        
public void setMemento(Memento memento)
        {
            _Container.Children.Clear();
            Memento memento1
= MementoClone(memento);
            
foreach (UIElement item in memento1.ContainerState)
            {
                ((Shape)item).Stroke
= System.Windows.Media.Brushes.Black;
                _Container.Children.Add(item);
            }
        }

        
public Memento MementoClone(Memento memento)
        {
            List
<UIElement> _ContainerState = new List<UIElement>();

            
foreach (UIElement item in memento.ContainerState)
            {
                
if (!(item is Thumb))
                {
                    UIElement newItem
= DeepClone(item);
                    _ContainerState.Add(newItem);
                }
            }

            
return new Memento(_ContainerState);

        }
        
private UIElement DeepClone(UIElement element)
        {
            
string shapestring = XamlWriter.Save(element);
            StringReader stringReader
= new StringReader(shapestring);
            XmlTextReader xmlTextReader
= new XmlTextReader(stringReader);
            UIElement DeepCopyobject
= (UIElement)XamlReader.Load(xmlTextReader);
            
return DeepCopyobject;
        }
    }

  GetMemento() 方法深度拷贝画布的UIelement集合来创建一个备忘录并将其放回给调用方。SetMemento(Memento memento)方法首先清空画布然后通过将备忘录的每个对象添加给Canvas来设置备忘录。DeepClone(UIElement element)方法仅创建一个UIelement对象的深度拷贝。

1
相关文章