簡體   English   中英

觀察對象圖的變化

[英]Watch an object graph for changes

有沒有一種方法可以監視對象圖上任何對象的更改,並根據該更改執行某些操作?

可以說我有以下幾點:

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類中使用膠水代碼監視BarItems的更改,並連接到其PropertyChanged 這似乎有點混亂,並且容易出現錯誤。 有沒有更好的辦法?

與其引發對象自身屬性更改事件,不如說它們可以引發共享事件。 例如:

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();
};

我剛剛在http://www.lennybacon.com/ReBlinderFleckChangeTracking.aspx上閱讀了有關該問題的有趣博客文章

帖子是用德語編寫的,但由於它主要是代碼,所以應該可以。

希望這可以幫助!

我過去做的方法是創建一個單獨的ChangeTracker類,該類具有一種將對象注冊到其中的方法。 在該方法內部,使用反射來瀏覽已注冊的對象,並在實現INotifyPropertyChanged的每個屬性上掛入事件。

然后,您可以將方法添加到ChangeTracker以詢問狀態,例如IsDirty(),甚至可以在ChangeTracker上實現INotifyPropertyChanged。

(請確保在ChangeTracker上實現並使用IDisposable,並在那時刪除所有事件處理程序)。

對於實現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();
}

編輯>在添加項目時要執行以下操作:

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);

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM