1

オブジェクトグラフでオブジェクトの変更を監視し、その変更に基づいて何かを行う方法はありますか?

私が次のものを持っているとしましょう:

public class Main:INotifyPropertyChanged
{
    public ObservableCollection<Foo> FooItems { get; }
    public ObservableCollection<Bar> BarItems { get; }
}

public class Foo:INotifyPropertyChanged

public class Bar:INotifyPropertyChanged
{
    public ObservableCollection<Other> OtherItems { get; }
}

public class Other:INotifyPropertyChanged

すべてのオブジェクトにある種の変更通知システムを実装する最良の方法は何でしょうか? たとえば、自動保存では、変更が発生すると、システムがMainクラスをシリアル化します。

変更をMain監視し、それらに接続するクラスにグルーコードを含める必要がありますか? これは少し面倒で、エラーが発生しやすいようです。より良い方法はありますか?BarItemsPropertyChanged

4

4 に答える 4

3

オブジェクトが独自のプロパティ変更イベントを発生させるのではなく、代わりに共有イベントを発生させる可能性があります。例えば:

public class SharedChangeNotifier
{
    public static event EventHandler<DataChangedEventArgs> SharedChangeEvent;

    protected void RaiseChangeEvent()
    {
        if (SharedChangeNotifier.SharedChangeEvent != null)
        {
            SharedChangeNotifier.SharedChangeEvent(
                this, new DataChangedEventArgs());
        }
    }
}

public class Foo : SharedChangeNotifier
{
    public int MyProperty
    {
        get { ... }
        set
        {
            ...
            RaiseChangeEvent();
        }
    }
}

次に、次のように、イベントハンドラーを静的SharedChangeNotifierのSharedChangeEventにアタッチして、SharedChangeNotifierから派生したオブジェクトが変更されたときに通知を受け取ることができます。

SharedChangeNotifier.SharedChangeEvent += (sender, args) => {
    DoWhatever();
};
于 2009-07-06T08:20:20.447 に答える
0

私が過去に行った方法は、オブジェクトを登録するメソッドを使用して別の ChangeTracker クラスを作成することでした。そのメソッド内で、リフレクションを使用して登録済みオブジェクトを探索し、INotifyPropertyChanged を実装する各プロパティのイベントにフックします。

その後、IsDirty() などの状態を調べるメソッドを ChangeTracker に追加したり、ChangeTracker に INotifyPropertyChanged を実装したりすることもできます。

(必ず ChangeTracker で IDisposable を実装して使用し、その時点ですべてのイベント ハンドラーを削除してください)。

于 2009-07-06T18:29:11.530 に答える
0

INotifyPropertyChanged イベントを実装するすべてのアイテムに対して同じハンドラーを使用できます。

foreach (INotifyPropertyChanged obj in FooItems)
    obj.PropertyChanged+= this.modified;

// likewise for bar items, and when items are added

private void modified(object sender, EventArgs args)
{
    this.Save();
}

edit> アイテムが追加されたときに同じことを行うには:

private void addToList<T>(ref List<T> l, T item) where T : INotifyPropertyChanged
{
    item.PropertyChanged += this.modified;
    l.Add(item);
}

次を使用して呼び出します。

Foo item = new Foo();
List<Foo> fooItems = new List<Foo>();

addToList<Foo>(ref fooItems, item);
于 2009-07-06T18:30:40.077 に答える
0

http://www.lennybacon.com/ReBlinderFleckChangeTracking.aspxで、その問題に関する興味深いブログ投稿を読みました。

投稿はドイツ語ですが、ほとんどコードなので問題ありません。

お役に立てれば!

于 2009-07-06T08:01:35.353 に答える