user3299166
user3299166

Reputation: 191

Observable Collection within a Property of Another Class

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

Answers (2)

Pragmateek
Pragmateek

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

Rohit Vats
Rohit Vats

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

Related Questions