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
事件。
我的目标是处理 Class1
中 NestedClass
的所有项目的所有更改,以获取数据已更改的信息(并将此信息传递给其父级)。
问题是我有多个嵌套集合,它们通知父级 class Class1
并且它成功地将事件冒泡到其父级。但是,一个集合将更改通知父 Class1
,但 Class1
中的 handler
为空,结果 Class1
不会将事件冒泡到其父 class(此处未显示为无关紧要)。我经历了调试器,但无法找到问题出在哪里。当其他嵌套集合调用父集合的 OnPropertyChanged
时,handler
不为空,一切正常。
编辑:仅当 Class1
和 NestedClass
对象由 XML 反序列化器生成时才会出现此问题。
我在 SO 上阅读了很多类似的帖子,但大多数都是关于视图中无效的 DataContext,这不是我的情况(我相信)。我还可以检查什么来找到问题的根源?
您可能需要考虑切换到 BindingList<T>
而不是 ObserveableCollection<T>
,它已经内置了您在 childOnCollectionChanged
中执行的逻辑。只需确保 RaiseListChangedEvents
设置为 true 并且 ListChanged
事件将随着 args.ListChangedType == ListChangedType.ItemChanged
任何时候其中一名成员引发其 PropertyChanged
事件而引发。
假设,我有以下 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
事件。
我的目标是处理 Class1
中 NestedClass
的所有项目的所有更改,以获取数据已更改的信息(并将此信息传递给其父级)。
问题是我有多个嵌套集合,它们通知父级 class Class1
并且它成功地将事件冒泡到其父级。但是,一个集合将更改通知父 Class1
,但 Class1
中的 handler
为空,结果 Class1
不会将事件冒泡到其父 class(此处未显示为无关紧要)。我经历了调试器,但无法找到问题出在哪里。当其他嵌套集合调用父集合的 OnPropertyChanged
时,handler
不为空,一切正常。
编辑:仅当 Class1
和 NestedClass
对象由 XML 反序列化器生成时才会出现此问题。
我在 SO 上阅读了很多类似的帖子,但大多数都是关于视图中无效的 DataContext,这不是我的情况(我相信)。我还可以检查什么来找到问题的根源?
您可能需要考虑切换到 BindingList<T>
而不是 ObserveableCollection<T>
,它已经内置了您在 childOnCollectionChanged
中执行的逻辑。只需确保 RaiseListChangedEvents
设置为 true 并且 ListChanged
事件将随着 args.ListChangedType == ListChangedType.ItemChanged
任何时候其中一名成员引发其 PropertyChanged
事件而引发。