




已阅读5页,还剩3页未读, 继续免费阅读
版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领
文档简介
关于Undo/Redo实现的基本思想 正如我们所知,应用程序在每次操作后改变其状态。当操作应用程序时,它的状态会发生改变。所以,若有人想要做撤销,他不得不回到先前的状态。因此,为了能够回到先前状态,我们需要在应用程序运行时存储它的状态。要支持重做,我们不得不从目前状态跳到下一个状态。 第一篇:C#中使用单个对象的方法实现Undo/Redo 为了实现Undo/Redo,我们不得不存储应用程序的状态并在撤销时跳到前一个状态而在重做时跳到下一个状态。因此我们需要维护应用程序的状态来支持Undo/Redo。在所有三种方法中,应用程序状态的维护用到了两个栈。一个栈包含用于撤销操作的状态,第二个包含用于重做的状态。撤销操作弹出撤销栈以获取前一个状态并将其设置给应用程序。同样的,重做操作弹出重做栈以获取下一个状态并将其设置给应用程序。 现在,我们知道了Undo/Redo的实现操作都是关于保持应用程序每次操作后的状态。现在的问题是该方法如何保存状态。在命令模式中,我们将单个操作的变化保存在一个ICommand对象中,它的目的在于把这种特殊类型的操作看作状态。关于命令模式 这里我并不打算讨论命令模式,你可从这和这了解该模式相关信息。 如何应用命令模式对任意应用程序Undo/Redo操作建模? 命令模式如何对任意应用程序Undo/Redo操作建模将在以下步骤中讨论: 步骤 首先识别出你希望哪些操作能支持Undo/Redo,并识别出操作将要应用的那些对象以及Undo/Redo操作的容器。 步骤 对每个识别出的操作,使命令类继承自ICommand。每个命令类将包含它所代表的操作进行Undo/Redo时所需的属性。ICommand接口如下:interfaceICommandvoidExecute();voidUnExecute(); 在Execute()方法中,你将利用命令的属性来完成动作。在Unexecuted ()方法中,你将利用命令的属性完成撤销操作。这里命令的属性保存它对应的命令完成Undo/Redo需要的变化,以及它改变的那些对象的引用。 特别注意:如果同一个操作对不同对象表现不同的行为,那么你不得不为此操作准备多重命令。这是针对每个对象类型的操作命令。 步骤3 然后创建一个名为UndoRedo的类,它包含两个栈。第一个用于Undo操作,第二个用于Redo操作。该类实现Undo方法,Redo方法和许多的InsertInUnDoRedo方法以在Undo / Redo系统中插入ICommand对象。当InsertInUnDoRedo方法被调用,然后ICommand对象被插入Undo栈,使Undo / Redo操作可用并清除Redostack。 在Undo操作中:首先检查UndoStack是否为空。如果为空则返回否则继续。然后从UndoStack中弹出一个ICommand对象。再次把该命令压入RedoStack。最后调用Icommand对象的Unexecute方法。 在Redo操作中: 首先检查RedoStack是否为空。若为空则返回,否则继续。 然后从RedoStack中弹出一个Icommand对象。 再次把该命令压入Undostack。 最后调用Icommand对象的execute方法。 步骤4 当你执行应用程序内不同的操作时,创建该操作类型的Command对象并通过名为InsertInUnDoRedo的方法将其压入Undo/Redo系统。当你需要做Undo操作时,只要调用应用程序中UndoRedo类的Undo方法,而当你想做Redo操作时,你只要调用应用程序的redo操作。示例应用程序描述 这个示范WPF绘制应用程序用来作为结合Undo/Redo操作的案例。该WPF应用程序示例支持四种操作:插入对象、删除对象、移动对象和调整对象的尺寸,它还有两种类型的几何对象:矩形和多边形。它使用画布作为包含这些几何对象的容器。 现在,在此系列文章中,我们可以看到如何让这四个操作支持Undo/Redo。在第一部分,使用单个对象表示变化的方法实现。在第二部分,使用命令模式实现而在第三部分,使用备忘录模式实现。 使用命令模式实现示例应用程序的Undo/Redo 利用命令模式对示范应用程序Undo/Redo的实现将在以下步骤中讨论: 步骤1 在示范应用程序中有四种操作,它们是移动、调整尺寸、插入和删除。对象是矩形、椭圆,而容器是一个WPF画布。 步骤2 现在我们要为四种操作创建四个继承ICommand接口的命令类。classMoveCommand : ICommandprivateThickness _ChangeOfMargin;privateFrameworkElement _UiElement;publicMoveCommand(Thickness margin, FrameworkElement uiElement)_ChangeOfMargin=margin;_UiElement=uiElement;#regionICommand MemberspublicvoidExecute()_UiElement.Margin=newThickness(_UiElement.Margin.Left+ _ChangeOfMargin.Left, _UiElement.Margin.Top+_ChangeOfMargin.Top, _UiElement.Margin.Right+ _ChangeOfMargin.Right, _UiElement.Margin.Bottom+ _ChangeOfMargin.Bottom);publicvoidUnExecute()_UiElement.Margin=newThickness(_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的边距变化。classResizeCommand : ICommandprivateThickness _ChangeOfMargin;privatedouble_ChangeofWidth;privatedouble_Changeofheight;privateFrameworkElement _UiElement;publicResizeCommand(Thickness margin,doublewidth,doubleheight, FrameworkElement uiElement)_ChangeOfMargin=margin;_ChangeofWidth=width;_Changeofheight=height;_UiElement=uiElement;#regionICommand MemberspublicvoidExecute()_UiElement.Height=_UiElement.Height+_Changeofheight;_UiElement.Width=_UiElement.Width+_ChangeofWidth;_UiElement.Margin=newThickness(_UiElement.Margin.Left+_ChangeOfMargin.Left,_UiElement.Margin.Top+_ChangeOfMargin.Top, _UiElement.Margin.Right+_ChangeOfMargin.Right, _UiElement.Margin.Bottom+_ChangeOfMargin.Bottom);publicvoidUnExecute()_UiElement.Height=_UiElement.Height-_Changeofheight;_UiElement.Width=_UiElement.Width-_ChangeofWidth;_UiElement.Margin=newThickness(_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的边距变化、高度变化和宽度变化。classInsertCommand : ICommandprivateFrameworkElement _UiElement;privateCanvas _Container;publicInsertCommand(FrameworkElement uiElement, Canvas container)_UiElement=uiElement;_Container=container;#regionICommand MemberspublicvoidExecute()if(!_Container.Children.Contains(_UiElement)_Container.Children.Add(_UiElement);publicvoidUnExecute()_Container.Children.Remove(_UiElement);#endregion 插入操作插入一个几何对象到面板,插入命令包含几何对象和对Canvas的引用。在插入命令中,Execute方法添加对象到画布,而Unexecute方法从画布中删除该对象。classDeleteCommand : ICommandprivateFrameworkElement _UiElement;privateCanvas _Container;publicDeleteCommand(FrameworkElement uiElement, Canvas container)_UiElement=uiElement;_Container=container;#regionICommand MemberspublicvoidExecute()_Container.Children.Remove(_UiElement);publicvoidUnExecute()_Container.Children.Add(_UiElement);#endregion 因为删除操作从面板中删除一个几何对象,因此删除命令带有几何对象和画布的应用。在删除对象中,Execute方法从画布中删除对象,而Unexecute方法添加这个对象到画布。步骤3 现在我们将根据通用方法的描述实现UndoRedo类。publicclassUnDoRedoprivateStack_Undocommands=newStack();privateStack_Redocommands=newStack();privateCanvas _Container;publicCanvas Containergetreturn_Container; set _Container=value; publicvoidRedo(intlevels)for(inti=1; i=levels; i+)if(_Redocommands.Count!=0)ICommand command=_Redocommands.Pop();command.Execute();_Undocommands.Push(command);publicvoidUndo(intlevels)for(inti=1; i=levels; i+)if(_Undocommands.Count!=0)ICommand command=_Undocommands.Pop();command.UnExecute();_Redocommands.Push(command);#regionUndoHelperFunctionspublicvoidInsertInUnDoRedoForInsert(FrameworkElement ApbOrDevice)ICommand cmd=newInsertCommand(ApbOrDevice, Container);_Undocommands.Push(cmd);_Redocommands.Clear();publicvoidInsertInUnDoRedoForDelete(FrameworkElement ApbOrDevice)ICommand cmd=newDeleteCommand(ApbOrDevice, Container);_Undocommands.Push(cmd);_Redocommands.Clear();publicvoidInsertInUnDoRedoForMove(Point margin, FrameworkElement UIelement)ICommand cmd=newMoveCommand(newThickness (margin.X, margin.Y,0,0), UIelement);_Undocommands.Push(cmd);_Redocommands.Clear();publicvoidInsertInUnDoRedoForResize(Point margin,doublewidth,doubleheight, FrameworkElement UIelement)ICommand cmd=newResizeCommand(ne
温馨提示
- 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
- 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
- 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
- 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
- 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
- 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
- 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。
最新文档
- 2024-2025学年证券从业资格模拟试题带答案详解(综合卷)
- 小口径顶管施工方案
- 客家方言防疫指南解读
- 2026届吉林省农安县三岗中学九上化学期中考试模拟试题含解析
- 2026届浙江省绍兴市迪荡新区九年级化学第一学期期中考试试题含解析
- 2026届衡水市重点中学英语九年级第一学期期末学业水平测试试题含解析
- 委农办半年工作总结
- 食堂消防安全培训大纲
- 绿色学校知识培训大纲
- 教师企业实践培训汇报
- 俄乌局势进展
- 2025甘肃兰州兴蓉环境发展有限责任公司招聘内控管理岗等岗位5人笔试模拟试题及答案解析
- 苏教版三年级上册数学全册教学设计(配2025年秋新版教材)
- 用电安全与消防知识培训课件
- 2025年法考真题及答案
- 基孔肯雅热防护知识科普课件
- 2025年思想政治教育实践考试试题及答案解析
- 志愿者个人汇报
- 医院安全教育培训课件
- 食品安全规章制度目录16项
- 2025至2030年中国导热散热材料行业市场发展现状及投资方向研究报告
评论
0/150
提交评论