2013-02-01 31 views
0

我一直在研究涉及移动多种形状的WPF应用程序。它主要是MVVM并严重依赖于命令。直到最近,我还没有担心撤销/重做。我认为这不会太困难,因为我的大部分更改都涉及继承实现ICommand的基类CommandBase的命令。使用命令模式和ICommand对撤销/重做进行参数跟踪。存储多个命令?

到目前为止,我添加了另一个名为IUndoCommand的接口,它使用ICommand。我添加了一个Undo方法,可以执行撤消操作时所需的操作。

我将为撤销和重做使用堆栈,但我遇到了Execute/Undo方法的参数问题。有没有一种合适的方式来存储这些类型对象的参数?向IUndoCommand添加字段/方法是否明智?如果是的话,我应该将它设置在Execute方法或构造函数中(如果我甚至可以)。

如果不是,我应该将它作为堆栈中自己的对象传递给它?其次,(尽管这可能是它自己的问题)是否有更好的数据结构来跟踪多个命令?我目前有一个循环运行多个命令来移动多个选定的形状,并希望允许一个撤销全部撤消它们。我想我可以将它转换为自己的命令并将命令传递给它,但是我又是新手,宁愿做正确的事情。

感谢您的阅读和任何帮助将不胜感激。

来源:

Code Project VisualStudioMagazine StackOverFlow

+0

你看的时代报设计模式?这是专门用于撤消的目的。正如你对队列所做的那样,重做只是模式的反转。 http://en.wikipedia.org/wiki/Memento_pattern –

+0

我看到了,这是我最初开始工作。我觉得这样可以给我更多的控制权,而且我已经做得更好。我有一个DrawingEditViewModel设置为我的datacontext。这有可观察的与模型交互的视图模型集合。它还会跟踪我的内容宽度/高度和消息(因为存在缩放)。我可以将宽度/高度/缩放移动到另一个类,但仍然需要访问它。 –

+0

这是一个问题,因为在设计模式中最简单的解决方案是整个视图模型的深度复制是正确的?这会导致放大/缩小变化被保存为一个非常烦人的步骤。用户必须控制+ z 8次才能回到最后的视图位置。我希望这是有道理的.. –

回答

1

由于接口不需要访问数据(它应该只需要一个Undo()/Redo()方法对,并且潜在地可用于它是否能标志撤消),它根本不需要了解参数。

一个选项可能是使您的实现IUndoCommand通用。然后,您可以使用它以类型安全的方式存储参数。然后

CommandBase类可以是通用的,即:

class CommandBase<T> : ICommand, IUndoCommand 
{ 
    // You could then store the parameter directly... 
    public T Parameter { get; private set; } 
} 
+0

我明白了,我喜欢这个解决方案,但是可以将它设置在Execute方法中吗?我会这么认为,因为除非调用Execute,否则命令不会被添加到任何堆栈中。我只是不确定没有更好的方法.. –