我目前正在寻找将撤消/重做(基于本文)与使用 ICommand 的命令模式结合起来。阅读有关 CanExecute 和 CanExecuteChanged 的想法后,我发现了将更改的状态传播到所有已注册 UIElement 的 CommandManager。但是,如果命令本身存储更改的数据,则似乎很难将这两者结合起来。这是当前情况的示例:
interface IUndoCommand : ICommand
{
void Undo();
}
和实施:
public class SampleCommand : IUndoCommand
{
private Point oldPosition;
private Shape shape;
// Gets the currently moved shape object
public MoveCommand(Shape shape, Point oldPosition)
{
this.oldPosition = oldPosition;
this.newPosition = new Point(Cavas.GetLeft(shape),Canvas.GetTop(shape));
this.shape = shape;
}
public void Execute(object parameter)
{
Model.PersistChanges(shape, newPosition);
}
public void Undo()
{
Model.PersistChanges(shape, oldPosition);
}
public bool CanExecute(object parameter)
{
}
public event EventHandler CanExecuteChanged;
}
冲突
在此实现中,命令存储更改,因此每次执行时都需要创建一个新实例。然而,CommandManager 会跟踪状态并通知 UIElements。如果我在那里注册命令的每个实例,一个 UIElement 就会有几个相等的命令竞争 CanExecute 状态。这似乎打破了这个想法,那么它是如何工作的呢?
当然,我可以将重做/撤消所需的状态从命令移动到模型,并准确注册一个(静态)命令实例,该实例将被全面使用。但实际上我喜欢在命令中存储状态的想法。
如果我省略 ICommand 用法,wpftutorial.net的示例将起作用 - 尽管我还没有完全了解那里的操作/撤消操作的想法。
问题
您如何结合这些方法,撤消/重做 + CommandManager?是实现在模型中保存状态的唯一解决方案(以 MVVM 为基础)还是有其他机会?
编辑:
是否可以在仍然使用 CommandManager 的命令中保存状态?ICommand-Interface 提供了跟踪 CanExecute-State 的功能,这是一个好主意。但是,我看不到在保存命令中的状态的同时保留这个想法的可能性(因此需要几个不同的实例)。