2

私は今、ちょっと混乱していると思います。

フォームの元に戻す機能とやり直し機能を実装する必要があります。簡単にするために、変更されたコントロールと、Focusを離れたときの値のみを保存するとします。

「タイムライン」を行き来できるようにこの情報を保存するにはどうすればよいですか。

スタックを使用することを考えましたが、小さなデモをテストしているときに、軽度の動脈瘤があり、ここにいます。

コードが必要ですが、実際にはそうではありませんが、役に立ちます。実装する必要のあるアルゴリズムにもっと興味があります。助言がありますか?

4

4 に答える 4

4

IUndoableActionインターフェイスを使用します。実装では、実行および元に戻す必要のあるデータをすべて保存できます。そうです、スタックを使用してそれらを保持します。

interface IUndoableAction
{
    void Do();
    void Undo();
}
Stack<IUndoableAction> Actions;

それぞれの種類のアクションは、DoメソッドとUndoメソッドを実装します。

次に、どこかに次の2つの方法があります。

    void PerformAction(IUndoableActionaction)
    {
        Actions.Push(action);
        action.Do();
    }

    void Undo()
    {
        var action = Actions.Pop();
        action.Undo();
    }

アクションクラスに何を保存するかについては、一部のアクションは古い値を保存するだけで済みます。ただし、スプレッドシートの2つの行を入れ替えるアクションが発生したことがあります。すべてのセルの値を両方の行に保存しませんでした。元に戻すことができるように、行のインデックスを保存しただけです。すべてのアクションに対してその状態をすべて保存すると、大量のメモリを簡単に埋めることができます。

次に、REDOスタックも必要です。アクションを元に戻すと、そのアクションはREDOスタックにプッシュされます。新しいアクションが実行されるときにREDOスタックをクリアする必要があるため、問題が発生することはありません。

于 2011-07-28T16:31:44.423 に答える
4

スタックに「変更」をプッシュし、元に戻すときにスタックから「変更」をポップすると、スタックは完璧です。次に、そのポップされた変更を、やり直しを表す別のスタックにプッシュします。将来のある時点で、できれば保存時に、両方のスタックをクリアします。

変更の種類を記録したり、古い値と新しい値を理解したりする必要があるため、実際にはそれほど単純ではありません。したがって、元にスキャンスタックからポップする場合、ポップするものは、前の値が何であり、何がそれを制御するかを説明する必要があります。に設定されました。

REDOスタックの逆の場合、新しい値が何であり、どこに移動したかを理解する必要があります。しかし、はい、2つのスタックのアイデアは、自作の元に戻すための良いスタートです。

ビジネスオブジェクトベースのundoの良い例は、CSLA.NETですUndoableBase

http://www.lhotka.net/cslanet/

http://www.koders.com/csharp/fidCF6AB2CF035B830FF6E40AA22C8AE7B135BE1FC0.aspx?s=serializationinfo

ただし、これはオブジェクトの状態のスナップショットを記録するため、フォームベースの概念よりも高度になります。ただし、CSLA.NETは完全なデータバインディングサポートを提供するため、から継承するデータバインディングオブジェクトUndoableBaseは、UIで元に戻る(やり直しではない)を自然にサポートします。

于 2011-07-28T16:27:59.117 に答える
4

はい、スタックを使用します。それを行うにはいくつかの方法があります。これらの参考文献を読んでください:

http://en.wikipedia.org/wiki/Command_pattern

http://en.wikipedia.org/wiki/Memento_pattern

それぞれに長所/短所があります。

于 2011-07-28T16:28:52.760 に答える
0

おそらく最も簡単なのは、元に戻る/やり直しスタックの組み合わせを使用することです。

別の方法は、配列またはアクションのリストを用意し、配列内のインデックスへのポインターをインクリメント/デクリメントすることです。アクションを元に戻すと、インデックスが1つ前に移動し、アクションをやり直すと、インデックスが1つ前に移動します。ここでの利点は、アクションごとにポップアンドプッシュシーケンスを必要としないことです。

考慮事項:

  • 何度か元に戻してからアクションを実行する場合は、すべてのやり直しアクションを削除する必要があります。
  • 元に戻す/やり直しを実行する前に、境界を確認し、元に戻す/やり直しに使用できるアクションがあることを確認してください。
于 2011-07-28T16:54:20.877 に答える