class 层次结构中的 INotifyPropertyChanged 冒泡

INotifyPropertyChanged bubbling in class hierarchy

假设,我有以下 class 层次结构:

public NestedClass : INotifyPropertyChanged {
    string prop1;

    public String  Prop1 {
        get { return prop1; }
        set {
            prop1 = value;
            OnPropertyChanged("Prop1");
        }
    }

    void OnPropertyChanged(String name) {
        PropertyChangedEventHandler handler = PropertyChanged;
        if (handler != null) {
            handler(this, new PropertyChangedEventArgs(name));
        }
    }
    public event PropertyChangedEventHandler PropertyChanged;
}

public Class1 : INotifyPropertyChanged {
    ObservableCollection<NestedClass> collection;

    public Class1() {
        collection = new ObservableCollection<NestedClass>();
    }

    public ObservableCollection<NestedClass>  Collection {
        get { return collection; }
        set {
            if (collection != null) {
                collection.CollectionChanged -= childOnCollectionChanged;
            }
            collection = value;
            if (collection != null) {
                collection.CollectionChanged += childOnCollectionChanged;
            }
        }
    }

    void childOnCollectionChanged(Object sender, NotifyCollectionChangedEventArgs e) {
        switch (e.Action) {
            case NotifyCollectionChangedAction.Add:
                ((INotifyPropertyChanged)e.NewItems[0]).PropertyChanged += childOnPropertyChanged;
                break;
            case NotifyCollectionChangedAction.Remove:
                ((INotifyPropertyChanged)e.OldItems[0]).PropertyChanged -= childOnPropertyChanged;
                break;
            case NotifyCollectionChangedAction.Reset:
                if (e.OldItems == null) { break; }
                foreach (INotifyPropertyChanged itemToRemove in e.OldItems) {
                    itemToRemove.PropertyChanged -= childOnPropertyChanged;
                }
                break;
        }
    }
    void childOnPropertyChanged(Object sender, PropertyChangedEventArgs e) {
        OnPropertyChanged("nested");
    }

    void OnPropertyChanged(String name) {
        PropertyChangedEventHandler handler = PropertyChanged;
        if (handler != null) {
            handler(this, new PropertyChangedEventArgs(name));
        }
    }
    public event PropertyChangedEventHandler PropertyChanged;
}

有 class Class1,其中包含一些属性和不同 classes 的几个集合。所有集合都定义在与 NestedClass 集合相同的 was 中。它们已正确绑定到 UI,我在那里没有问题。

Class1 对象和嵌套的 objects/collections 可以在运行时创建,或者可以由 XML 反序列化器生成。为了正确处理反序列化集合,我必须在分配集合时订阅每个集合项的 INotifyPropertyChanged 事件。

我的目标是处理 Class1NestedClass 的所有项目的所有更改,以获取数据已更改的信息(并将此信息传递给其父级)。

问题是我有多个嵌套集合,它们通知父级 class Class1 并且它成功地将事件冒泡到其父级。但是,一个集合将更改通知父 Class1,但 Class1 中的 handler 为空,结果 Class1 不会将事件冒泡到其父 class(此处未显示为无关紧要)。我经历了调试器,但无法找到问题出在哪里。当其他嵌套集合调用父集合的 OnPropertyChanged 时,handler 不为空,一切正常。

编辑:仅当 Class1NestedClass 对象由 XML 反序列化器生成时才会出现此问题。

我在 SO 上阅读了很多类似的帖子,但大多数都是关于视图中无效的 DataContext,这不是我的情况(我相信)。我还可以检查什么来找到问题的根源?

您可能需要考虑切换到 BindingList<T> 而不是 ObserveableCollection<T>,它已经内置了您在 childOnCollectionChanged 中执行的逻辑。只需确保 RaiseListChangedEvents 设置为 true 并且 ListChanged 事件将随着 args.ListChangedType == ListChangedType.ItemChanged 任何时候其中一名成员引发其 PropertyChanged 事件而引发。