7

ユーザーがGUIを介して既存のオブジェクト(正確には「フィルター」ドメインオブジェクト)を編集できるシステムに取り組んでいます。UI のヒントとして、ユーザーが実際にオブジェクトに何かを変更した場合にのみ、保存ボタンを有効にしたいと考えています。誰かがこの問題を経験したことがあるかどうか、そしてこれにアプローチする最善の方法は何だろうと思っていました.

ドメイン オブジェクトに isDirty() フラグを追加することを考えていました。ユーザーがフィルターの編集を開始したら、コピーを作成して GUI に渡し、ユーザーがコピーを変更できるようにします。isDirty() フラグのバインディングは、保存ボタンを有効/無効にします。保存すると、相違点が元のオブジェクトにマージされて永続化されます。

さらに、ユーザーがオブジェクトに加えた変更を元に戻すとどうなるかを考えていました。その場合、isDirty() フラグは false を返す必要があります。したがって、これを達成する唯一の方法は、各プロパティの元の値をドメイン オブジェクト内に保持することだと思います。

何か案は?

4

7 に答える 7

3

正しい!

さらに、次の2つのメソッドを公開できます。BeginEdit-このメソッドでは、IsDirtyフラグをTrueにマークします。変更を行っていることを意味します。変更を加える場合は、このメソッドを呼び出します

CancelEdit-このメソッドでは、IsDirtyフラグをFalseにリセットします。これは、編集プロセスを中止し、元の状態に戻ったことを意味します。行った変更をキャンセルする場合は、このメソッドを呼び出します。

また、変更が永続化されたら、IsDirtyフラグもFalseにリセットします。

これがお役に立てば幸いです。

于 2008-10-14T12:12:32.573 に答える
2

変更の追跡と元に戻すのに役立つ実装可能なインターフェイスがいくつかあります。INotifyPropertyChangedとIEditableObjectです。これらのインターフェイスは両方とも、オブジェクトがデータバインディングでうまく機能することを可能にします。

public class Person : INotifyPropertyChanged, IEditableObject
{
    private bool isDirty;

    public bool IsDirty
    {
        get { return isDirty; }
    }

    private string firstname = string.Empty;

    public string Firstname
    {
        get { return firstname; }
        set
        {
            if (firstname == value) return;
            firstname = value;
            NotifyPropertyChanged("Firstname");
        }
    }

    private string lastname = string.Empty;

    public string Lastname
    {
        get { return lastname; }
        set
        {
            if (lastname == value) return;
            lastname = value;
            NotifyPropertyChanged("Lastname");
        }
    }

    public event PropertyChangedEventHandler PropertyChanged;

    public void NotifyPropertyChanged(string propertyName)
    {
        isDirty = true;

        if (PropertyChanged != null)
            PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
    }

    private bool inTrans;
    private Person copy;

    public void BeginEdit()
    {
        if (!inTrans)
        {
            if (copy == null)
                copy = new Person();

            copy.isDirty = isDirty;
            copy.Firstname = Firstname;
            copy.Lastname = Lastname;


            inTrans = true;
            isDirty = false;
        }
    }

    public void CancelEdit()
    {
        if (inTrans)
        {
            isDirty = copy.isDirty;
            Firstname = copy.Firstname;
            Lastname = copy.Lastname;

            inTrans = false;
        }
    }

    public void EndEdit()
    {
        if (inTrans)
        {
            copy = null;
            inTrans = false;
        }
    }
}
于 2008-10-14T20:00:25.983 に答える
2

.NET フレームワークを使用している場合は、Rockford Lhotka による CSLA .NET フレームワーク ( http://www.lhotka.net/cslanet/Default.aspx ) を参照してください。

CSLA は、オブジェクトの状態管理 (IsDirty)、元に戻す機能、データ バインディングなどを含む成熟したフレームワークであり、無料でオープンソースです。

于 2008-10-14T12:25:16.277 に答える
1

編集中のオブジェクトのセットがある場合は、isDirty()のブールフラグ以上のものが必要になる可能性があります。この問題は、参照カウントと同じです。つまり、編集時にダーティカウントをインクリメントし、元に戻すときにデクリメントします。元に戻すをサポートしている場合は、かなり厄介なロジックになってしまうと思います。私はそれをあなたのドメインオブジェクトから遠ざけます。

于 2008-10-14T12:17:35.340 に答える
1

はい、これはうまくいきます。元に戻すのではなく、IsDirtyメソッドを使用して、何かがレコードを変更した可能性があることを示し、それが「レコード変更ロジックを実行しました」をトリガーします。私は独自のフレームワークを開発しました。このフレームワークでは、すべてのテーブルフィールドが実際にはオブジェクトのプロパティです。フィールドがオブジェクトに書き込まれるたびに、「isDirty」フラグが設定されます。オブジェクトの「SaveObject」メソッド(実際にはヘルパークラスですが、オブジェクトに簡単に含めることができますが、xml、データベースなど、さまざまな方法でオブジェクトを保存する機能が必要でした)で、IsDirtyをチェックします。 falseの場合、保存をスキップします。これにより、オブジェクトを変更する可能性があるたびにSaveObjectを呼び出し、フレームワークに処理させるため、ロジックが単純化されます。

于 2008-10-14T12:23:07.903 に答える
1

ドメインによっては、同等性を使用して違いをテストできます。元のオブジェクトを保持し、編集用にオブジェクトのコピーを作成します。編集が実行される可能性がある場合はいつでも、UI を適切に変更します。

この提案の利点は、ドメイン オブジェクトに GUI 固有の機能 (isDirty() フラグ) を固定するのではなく、YMMV を固定することです。

于 2008-10-14T12:27:15.510 に答える
1

「最後の保存以降のすべてを元に戻す」よりも大きな粒度で元に戻す操作をサポートしている場合は、元に戻すスタックをお勧めします。何かが編集されると、それ (または元に戻す操作のファンクターまたはデリゲート) がスタックに追加されます。元に戻すときは、スタックをポップして、ポップされた操作を元に戻すだけです。isDirty() フラグは、更新する追加のストレージやロジックではなく、元に戻すスタックにアイテムが含まれているかどうかを確認するだけです。

于 2008-10-14T12:27:52.637 に答える