观察对象图以了解更改

时间:2009-07-06 07:42:58

标签: c# .net design-patterns inotifypropertychanged

有没有办法观察对象图表中是否存在任何对象的更改,并根据该更改执行某些操作?

假设我有以下内容:

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挂钩吗?这看起来有点乱,而且容易出错。还有更好的方法吗?

4 个答案:

答案 0 :(得分: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();
};

答案 1 :(得分:0)

我刚刚在http://www.lennybacon.com/ReBlinderFleckChangeTracking.aspx

上阅读了有关该问题的有趣博文

帖子是德语的,但因为它主要是代码,所以应该没问题。

希望这有帮助!

答案 2 :(得分:0)

我过去的方式是创建一个单独的ChangeTracker类,其中包含一个将对象注册到其中的方法。在该方法中,使用反射来探索已注册的对象,并在其实现INotifyPropertyChanged的每个属性上挂钩事件。

然后,您可以向ChangeTracker添加方法以询问状态,例如IsDirty(),甚至在ChangeTracker上实现INotifyPropertyChanged。

(确保在ChangeTracker上实现并使用IDisposable,并在那时删除所有事件处理程序。)

答案 3 :(得分: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();
}

编辑&gt;要在添加项目时执行相同的操作:

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