2009-07-06 87 views
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课上看胶水代码,看BarItems的变化,连接到他们的PropertyChanged?这看起来有点乱,而且容易出错。有没有更好的办法?

回答

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

我可以做到这一点,但我也使用INotifyPropertyChanged接口进行数据绑定,所以这将是很好的你已经有什么了。但我会记住这一点。 – 2009-07-06 08:44:03

0

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

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

(请务必在ChangeTracker上实现并使用IDisposable,并在当时删除所有事件处理程序)。

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

编辑>为了做同样的当增加一个项目:

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

什么时候添加或删除FooItems项目? – 2009-07-06 23:07:28