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?这似乎有点混乱,而且对我来说容易出错。有没有更好的办法?

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

我刚刚在http://www.lennybacon.com/ReBlinderFleckChangeTracking.aspx上阅读了一篇关于该问题的有趣博文

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

希望这可以帮助!

于 2009-07-06T08:01:35.353 回答
0

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

然后,您可以向 ChangeTracker 添加方法来询问状态,例如 IsDirty(),甚至可以在 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();
}

编辑> 添加项目时执行相同操作:

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 回答