如何实现在.NET Windows应用程序“撤销”操作? [英] How to implement 'undo' operation in .net windows application?

查看:181
本文介绍了如何实现在.NET Windows应用程序“撤销”操作?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

假设,一个双赢的形式有一定的输入域和用户输入/再输入一些数据。

Assume that, a win form has certain input fields and user enters/re-enters some data.

如何保留由撤消操作?

只是我想知道完成它的最佳方式。

Just I want to know the best way to accomplish it.

推荐答案

有几个选项。重要的是,你开始在项目的早期设计它。试图将其添加到现有项目可以的非常的昂贵的,如果它不是设计时考虑了这种能力。

There are a few options. The important thing is that you start designing it in early in the project. Trying to add it to an existing project can be very expensive if it wasn't designed with this capability in mind.

有,你要利​​用一些基本的模式:

There are a few fundamental patterns that you'll want to take advantage of:

  1. MVC 或的观察者模式。第一个关键是没有这么多宗教或图案狂热者实现您的高层次的架构。什么的的重要的是,你的软件可以识别它的当前状态和显示状态之间的差异,并适当地分离出来。需要有一个共同的,明确定义你的视觉状态和应用程序状态之间的耦合。这将为您提供你需要创建一个命令的通用体系结构(见#2)。

  1. MVC or Observer pattern. The first key isn't so much the religious or pattern-zealot implementation of your high-level architecture. What is important is that your software recognizes the difference between its current state and the displayed state, and decouples appropriately. There needs to be a common, clearly-defined coupling between your visual state and your application state. This provides you with the common architecture you need to create a command (see #2).

命令的格局。你得到了很多优质的用命令方式(尽管它可以付出一些code,看起来像它应该是向导生成的费用)。你采取了命令模式的具体做法可能会有所不同(每个命令指定一个类实现通过覆盖与每多一个命令类通过事件处理程序,例如实现),但命令的动作类@Ralph建议构建一个堆栈各地。

The Command pattern. You get a lot of quality with the command pattern (though it can come at the cost of some code that looks like it should be wizard-generated). The specific approach you take to the command pattern may vary (one class per command with implementation via overrides versus one class per many commands with implementation via event handlers, e.g.), but commands are the "action" class that @Ralph suggested structuring a stack around.

这可能是一个有点棘手,但一般的做法是听取该会从视觉状态提交数据到应用程序状态的事件。该<一href="http://msdn.microsoft.com/en-us/library/system.windows.forms.control.validated.aspx"><$c$c>Validated事件可能是一个很好的钩为文本框。该<一href="http://msdn.microsoft.com/en-us/library/system.windows.forms.control.click.aspx"><$c$c>Click事件将使一个按钮更有意义。当这种情况发生提交,您将创建与该控件相关联的命令,试图执行命令,添加命令到您的撤消堆栈如果命令成功完成。现在你完全跟踪所发生的事情,准确的数据,它的发生与

This can be a bit tricky, but the general approach would be to listen for an event that would "commit" data from the visual state to the app state. The Validated event might be a good hook for a Textbox. The Click event would make more sense for a Button. When that commit happens, you create the command associated with that control, you attempt to execute the command, and you add the command to your undo stack if the command completes successfully. Now you're tracking exactly what's happening and exactly the data it's happening with.

备忘录模式。 @JP退出了最后一块拼图。您可以使用保存的命令纪念保存什么受影响的控件的状态是命令执行之前。这一点,再加上你的命令的接口的 UnExecute()成员,应该是最后的核心部分的设计则需要执行的任务。

The Memento pattern. @JP Pulled out the last piece of the puzzle. You can use a memento on the saved command to store what the affected control's state was before the command executed. This, combined with an UnExecute() member on your command's interface, should be the last core piece of design you need to perform your task.

关于这样的结构化方法的好处是,你现在有额外行为的自然延伸一点需要发生在一个命令的基础。事务是天作之合,例如。在我目前的项目中,我使用了WPF <一href="http://msdn.microsoft.com/en-us/library/system.windows.input.icommand.aspx"><$c$c>ICommand接口(在我的WinForms项目)提供有关反馈意见是否给定的命令<一href="http://msdn.microsoft.com/en-us/library/system.windows.input.icommand.canexecute.aspx"><$c$c>CanExecute()在任何给定的时间。这让我能够在一个纯粹的命令驱动的方式适当地禁用UI部件。 :)

The nice thing about a structured approach like this is that you now have a natural extension point for additional behavior that needs to happen on a command-basis. Transactions are a natural fit, for example. In my current project, I'm using the WPF ICommand interface (in my winforms project) to provide feedback about whether a given command CanExecute() at any given time. This lets me enable and disable UI widgets appropriately in a purely command-driven way. :)

不幸的是,还没有一个很大的支持,这种结构内置到的WinForms(据我所知),所以你需要从头开始构建大部分。没有单件是特别复杂的,但你可以找到自己产生的大多是-样板code相当数量的每个命令。这也是一个普遍的设计技术。为它是有效的,它必须始终如一地在整个应用程序的适当部分中。这使得改型的功能pretty的昂贵,特别是如果原来的code为紧耦合和无凝聚力

The unfortunate thing is that there isn't a lot of support for this structure built-in to Winforms (as far as I know), so you'll need to build most of it from scratch. No single piece is particularly complicated, but you can find yourself generating a fair amount of mostly-boilerplate code for each command. It's also a pervasive design technique. For it to be effective, it has to be used consistently throughout the appropriate portions of the application. This makes retrofitting the functionality pretty expensive, especially if the original code is tightly coupled and incohesive.

这篇关于如何实现在.NET Windows应用程序“撤销”操作?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆