5

我正在开发一个 Silverlight LoB 应用程序,设计师希望它有一个选项卡式界面,类似于 Visual Studio 的界面(我们可能会使用 Telerik Rad 控件来停靠选项卡)。完成原型后,界面到目前为止运行良好,但我在思考如何在 MVVM 项目中实现撤消/重做功能时遇到问题。

撤消/重做功能必须:

  1. 在撤消/重做时,恢复 UI 状态,即将焦点、选择等返回到更改所源自的控件(例如文本框)。
  2. 有一个按视图撤消/重做堆栈

通常,我会使用命令模式,但我不确定如何将其应用于 MVVM。

我使用命令和绑定来获得视图和视图模型的理想化松散耦合,但它使撤消/重做变得更加棘手,因为视图模型没有任何视图和状态的概念收到命令或更改绑定属性时的视图。似乎我需要某种服务跟踪,只要用户执行一些可撤消的操作并获取状态以供以后恢复,该视图就处于活动状态。

对于在 MVVM 中实施撤消/重做的最佳实践是否有任何共识?我对 Daniel Vaughan 在他的 Calcium 项目中如何做到这一点很感兴趣。Blend 显然是使用 MVVM 模式编写的,它的行为就像我希望我的应用程序那样,如果 MS 解释他们是如何做到的,那就太好了!

4

2 回答 2

2

您需要做的第一件事是确保将操作与界面完全分开。这意味着将所有影响数据的操作转变为离散的操作。这也意味着任何导致观点改变的因素也应该被记录为一个离散的动作。基本上,界面的状态应该只反映数据更改和基于命令的视图更改(请参阅下面关于视图更改的最后一条注释)。

我们以前使用的最成功的撤消系统允许嵌套 IUndoableCommand 对象。这些复合命令汇总为单个用户操作(您希望在撤消菜单中看到的那种操作)。

我注意到您提到跨视图使用撤消...对于多格式应用程序来说,这似乎是不寻常的行为。通常撤消仅在单个控件内和任何拖放操作中。例外情况通常是基于图形的界面(不是基于表单的)。在撤消期间更改表单相当于将 MS Word 切换到另一个文档并继续撤消......对于最终用户来说非常令人不安。可能希望让用户体验人员重新考虑设计的这一方面。只值我的 2 美分。

希望这可以帮助。

于 2010-08-25T18:01:25.223 回答
1

@詹姆斯科,

我已经为 WPF 应用程序实现了撤消/重做,并最终将我的撤消/重做代码发布到http://muf.codeplex.com/。您也可以通过 NuGet 获取它。只需寻找“MUF”或“Monitored Undo Framework”。它包括对 Silverlight 4.0 以及 .NET 3.5、4.0 和 WP7 的支持。

我的 WPF 应用程序也使用了 MVVM,并且在某些情况下,确实允许撤消选择更改等操作。我还跟踪了 WPF 框架中显示的活动“页面”,以便将用户移回应该应用撤消操作的页面。

该库采用灵活的方法来编写操作以撤消/重做每个步骤。最终,它只需要一个代表撤消和重做代表。您可以让这些代表做任何您喜欢的事情。库中包含一个默认实现,它简单地采用对象、属性名称、旧值和新值。它构造基于反射的委托,这些委托将根据需要应用旧值或新值。

至于隔离每个视图的更改,该库允许您为每个“文档”或“容器”保留一个单独的撤消/重做操作堆栈。您只需传递对容器的引用即可获得相关的撤消/重做堆栈。

最后,该库包括对批量更改的支持。这在多个动作应该作为一个单元一起撤消的时候很有用。

欢迎在 codeplex 网站 (http://muf.codeplex.com/) 上发表评论和提问。您还可以在那里找到完整的文档和示例应用程序。

于 2011-06-21T02:44:41.577 回答