WEB开发网
开发学院软件开发C语言 C#中使用单个对象的方法实现Undo/Redo 阅读

C#中使用单个对象的方法实现Undo/Redo

 2009-03-19 08:21:07 来源:WEB开发网   
核心提示: 步骤3现在我们得到包含边距、高度、宽度、动作类型、几何对象引用的ChangeRepresentationObject以支持所有操作的Undo/Redo,这里的几何对象引用被保存以便我们在对其进行Undo/Redo时获取,C#中使用单个对象的方法实现Undo/Redo(4),同样使动作类型e

步骤3

现在我们得到包含边距、高度、宽度、动作类型、几何对象引用的ChangeRepresentationObject以支持所有操作的Undo/Redo。这里的几何对象引用被保存以便我们在对其进行Undo/Redo时获取。同样使动作类型enum代表插入、删除、移动和调整尺寸操作。此动作类型enum被用作ChangeRepresentationObject的一部分。

CollapseCopy Code
public enum ActionType
{
Delete = 0,
Move = 1,
Resize = 2,
Insert = 3
} 
CollapseCopy Code
public class ChangeRepresentationObject
{
public ActionType Action;
public Point Margin;
public double Width;
public double height;
public FrameworkElement UiElement;
}

这里,已附上使用单个对象表示变化的方法实现Undo/Redo的项目。

步骤4&5

然后我们将包含两个ChangeRepresentationObject类型的栈的类命名为UndoRedo。一个栈用于撤销操作而另一个用于重做操作。类的代码如下:

CollapseCopy Code
public partial class UnDoRedo : IUndoRedo
{
private Stack _UndoActionsCollection = 
new Stack();
private Stack _RedoActionsCollection = 
new Stack();

#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

步骤6

在完成每个操作前,调用InsertObjectforUndoRedo方法。当用户界面上Undo被点击,我们调用UndoRedo类的Undo方法,而当用户界面上Redo被点击,我们调用UndoRedo类的redo方法。

这里,我们没有明确设置Undo栈和Redo栈的大小,因此,应用程序能具有的状态数目取决于系统的内存。

使用单个对象表示变化的方法时的变更管理

如果你想要用单个对象表示变化的方法来为新的操作支持Undo/Redo时,你不得不作一些改变。你不得不修改表示变化的对象,动作类型Enum并改变Undo/Redo方法的代码。所以,它的可维护性很低。

使用单个对象表示变化的方法的优缺点

它的优点是实现简单,而不需要知道任何的设计模式,你就可以实现Undo/Redo。

可维护性很低。代表该方法的对象包含很多额外信息,因为这里,单个对象用来容纳所有动作类型的数据。例如,对移动而言,我们只需保存移动相关的数据,而对调整尺寸,我们应该仅保存该操作相关的数据。所以,我们在保存冗余的数据。随着操作数目的增加,冗余也在增加。这并不是好的面向对象的设计。

上一页  1 2 3 4 

Tags:使用 单个 对象

编辑录入:爽爽 [复制链接] [打 印]
赞助商链接