2

私は現在、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 を追跡する機能を提供します。これは良いアイデアです。ただし、コマンドで状態を保存している間、このアイデアを維持する可能性はありません (したがって、いくつかの異なるインスタンスが必要です)。

4

1 に答える 1