私は現在、ICommand を使用して元に戻す/やり直し (この記事に基づく) とコマンド パターンを組み合わせることを検討していました。CanExecute と CanExecuteChanged の考え方を読んで、変更された状態をすべての登録済み UIElement に伝達する CommandManager を見つけました。ただし、コマンドが変更されたデータ自体を保存する場合、これら2つを組み合わせるのは難しいようです。現在の状況の例を次に示します。
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 に通知します。そこにコマンドの各インスタンスを登録すると、1 つの UIElement に複数の同等のコマンドがあり、CanExecute 状態について競合します。これはアイデアを壊しているように見えますが、どのように機能しますか?
もちろん、やり直し/元に戻すために必要な状態をコマンドからモデルに移動し、全体で使用されるコマンドの (静的) インスタンスを 1 つだけ登録することもできます。しかし、実際には、コマンドで状態をストローするというアイデアが気に入っています。
ICommand の使用法を省略した場合、wpftutorial.netの例が機能しますが、アクション/元に戻すアクションのアイデアは完全には得られませんでした。
質問
これらのアプローチ、元に戻す/やり直し + CommandManager をどのように組み合わせますか? モデルに状態を保存することを実現する唯一の解決策(MVVMをベースと見なす)ですか、それとも他の機会がありますか?
編集:
CommandManager を使用してコマンドの状態を保存することはできますか? ICommand-Interface は、CanExecute-State を追跡する機能を提供します。これは良いアイデアです。ただし、コマンドで状態を保存している間、このアイデアを維持する可能性はありません (したがって、いくつかの異なるインスタンスが必要です)。