步骤1
首先识别出你希望哪些操作能支持Undo/Redo。然后,识别出你将在哪个容器下支持Undo/Redo以及你希望哪些对象支持Undo/Redo。
步骤2
为了进一步处理每个Undo/Redo操作,识别出需要被保存的属性。
步骤3
然后创建一个类(ChangeRepresentationObject),它包含支持全部操作Undo/Redo的所有属性。同样,准备一个动作类型enum,它将代表全部操作。这个动作类型enum是ChangeRepresentationObject类的一部分。
步骤4
然后创建一个名为UndoRedo的类,它包含两个类型的ChangeRepresentationObject栈。一个用于撤销操作,一个用于重做操作。
步骤5
然后实现具体方法:Undo、 Redo、InsertObjectforUndoRedo。
在每个Undo操作中:
•首先检查Undo栈是否为空。
•如果不是,则弹出一个ChangeRepresentationObject并将其压入重做栈。
•检查动作类型。
•然后基于动作类型,利用ChangeRepresentationObject的属性完成撤销操作。
在每个Redo操作中,你几乎做与Undo同样的事。
•首先检查Redo栈是否为空。
•如果不是,弹出一个ChangeRepresentationObject,然后将其压入撤销栈。
•检查动作类型。
•然后基于动作的类型,利用ChangeRepresentationObject属性完成重做操作。
在InsertObjectforUndoRedo操作中,你只要把数据对象插入Undo栈并清空Redo栈中。
步骤6
然后,在完成每次操作前,调用InsertObjectforUndoRedo方法以对所有操作提供Undo/Redo支持。在用户界面上点击Undo时,只需调用UndoRedo类的Undo方法,而在用户界面上点击Redo时,只需调用UndoRedo类的redo方法。
public enum ActionType
{
Delete = 0,
Move = 1,
Resize = 2,
Insert = 3
}
public class ChangeRepresentationObject
{
public ActionType Action;
public Point Margin;
public double Width;
public double height;
public FrameworkElement UiElement;
}
interface IUndoRedo
{
void Undo(int level);
void Redo(int level);
void InsertObjectforUndoRedo(ChangeRepresentationObject dataobject);
}
public partial class UnDoRedo : IUndoRedo
{
private Stack<ChangeRepresentationObject> _UndoActionsCollection =
new Stack<ChangeRepresentationObject>();
private Stack<ChangeRepresentationObject> _RedoActionsCollection =
new Stack<ChangeRepresentationObject>();
#region IUndoRedo Members
public void Undo(int level)
{
for (int i = 1; i <= level; i++)
{
if (_UndoActionsCollection.Count == 0) return;
ChangeRepresentationObject Undostruct = _UndoActionsCollection.Pop();
if (Undostruct.Action == ActionType.Delete)
{
Container.Children.Add(Undostruct.UiElement);
this.RedoPushInUnDoForDelete(Undostruct.UiElement);
}
else if (Undostruct.Action == ActionType.Insert)
{
Container.Children.Remove(Undostruct.UiElement);
this.RedoPushInUnDoForInsert(Undostruct.UiElement);
}
else if (Undostruct.Action == ActionType.Resize)
{
if (_UndoActionsCollection.Count != 0)
{
Point previousMarginOfSelectedObject = new Point
(((FrameworkElement)Undostruct.UiElement).Margin.Left,
((FrameworkElement)Undostruct.UiElement).Margin.Top);
this.RedoPushInUnDoForResize(previousMarginOfSelectedObject,
Undostruct.UiElement.Width,
Undostruct.UiElement.Height, Undostruct.UiElement);
Undostruct.UiElement.Margin = new Thickness
(Undostruct.Margin.X, Undostruct.Margin.Y, 0, 0);
Undostruct.UiElement.Height = Undostruct.height;
Undostruct.UiElement.Width = Undostruct.Width;
}
}
else if (Undostruct.Action == ActionType.Move)
{
Point previousMarginOfSelectedObject = new Point
(((FrameworkElement)Undostruct.UiElement).Margin.Left,
((FrameworkElement)Undostruct.UiElement).Margin.Top);
this.RedoPushInUnDoForMove(previousMarginOfSelectedObject,
Undostruct.UiElement);
Undostruct.UiElement.Margin = new Thickness
(Undostruct.Margin.X, Undostruct.Margin.Y, 0, 0);
}
}
}
public void Redo(int level)
{
for (int i = 1; i <= level; i++)
{
if (_RedoActionsCollection.Count == 0) return;
ChangeRepresentationObject Undostruct = _RedoActionsCollection.Pop();
if (Undostruct.Action == ActionType.Delete)
{
Container.Children.Remove(Undostruct.UiElement);
this.PushInUnDoForDelete(Undostruct.UiElement);
}
else if (Undostruct.Action == ActionType.Insert)
{
Container.Children.Add(Undostruct.UiElement);
this.PushInUnDoForInsert(Undostruct.UiElement);
}
else if (Undostruct.Action == ActionType.Resize)
{
Point previousMarginOfSelectedObject = new Point
(((FrameworkElement)Undostruct.UiElement).Margin.Left,
((FrameworkElement)Undostruct.UiElement).Margin.Top);
this.PushInUnDoForResize(previousMarginOfSelectedObject,
Undostruct.UiElement.Width,
Undostruct.UiElement.Height, Undostruct.UiElement);
Undostruct.UiElement.Margin = new Thickness
(Undostruct.Margin.X, Undostruct.Margin.Y, 0, 0);
Undostruct.UiElement.Height = Undostruct.height;
Undostruct.UiElement.Width = Undostruct.Width;
}
else if (Undostruct.Action == ActionType.Move)
{
Point previousMarginOfSelectedObject = new Point
(((FrameworkElement)Undostruct.UiElement).Margin.Left,
((FrameworkElement)Undostruct.UiElement).Margin.Top);
this.PushInUnDoForMove(previousMarginOfSelectedObject,
Undostruct.UiElement);
Undostruct.UiElement.Margin = new Thickness
(Undostruct.Margin.X, Undostruct.Margin.Y, 0, 0);
}
}
}
public void InsertObjectforUndoRedo(ChangeRepresentationObject dataobject)
{
_UndoActionsCollection.Push(dataobject);_RedoActionsCollection.Clear();
}
#endregion
http://hi.baidu.com/light_black/blog/item/79325d232f416046925807e0.html