Reputation: 191
Suppose I have a class that implements INotifyPropertyChanged
, where the one of the properties is a class whose members are ObservableCollections
:
namespace Example
{
public class A : INotifyPropertyChanged
{
private B _prop;
public B Prop
{
get { return _prop; }
set
{
_prop = value;
NotifyPropertyChanged("Prop");
}
}
public A() { Prop = new B(); }
//"Some Property" related Prop.words
}
public class B
{
public ObservableCollection<String> words { get; set; }
public B() { words = new ObservableCollection<String>(); }
}
}
I am confused about how to notify when that property in class A
when Prop.words
changes. In which class do I implement the handler from INotifyCollectionChanged
?
EDIT: I didn't specify the context earlier, but I'm binding a WPF control on "Some Property" that i need to update when the Prop.words
changes.
Upvotes: 1
Views: 1468
Reputation: 13354
The client of the A
class should handle this.
IMHO raising PropertyChanged
when the underlying collection changes is breaking the functional contract of INotifyPropertyChanged
.
Moreover imagine you have an items control bound to the collection: each time the collection changes it will be entirely rebound because we notify that it has changed entirely, definitely not what you want!
A a = new A();
...
a.Prop.Words.CollectionChanged += ...
This is exactly what the WPF controls will do if you bind to the Prop
properties.
Note that from a dogmatic OO design perspective this is breaking the Law of Demeter, so you may make the Words collection surface into your A type to avoid this, but this is another issue/debate.
Upvotes: 0
Reputation: 81243
If class A needs to be notified, then you have to hook CollectionChanged in Class A only. Do that in property setter of Prop.
Make sure to unhook the handler in case property B gets set with new value to avoid any memory leaks.
public class A : INotifyPropertyChanged
{
private B _prop;
public B Prop
{
get { return _prop; }
set
{
if(_prop != null)
_prop.words.CollectionChanged -= words_CollectionChanged;
_prop = value;
if (_prop != null)
_prop.words.CollectionChanged += words_CollectionChanged;
NotifyPropertyChanged("Prop");
}
}
void words_CollectionChanged(object sender,
NotifyCollectionChangedEventArgs e)
{
// Notify other properties here.
}
public A() { Prop = new B(); }
//Some Property related Prop.words
}
Upvotes: 2