3

My question is almost like the following existing question: When nesting properties that implement INotifyPropertyChanged must the parent object propogate changes?

My question is If I have three levels as follows Person Contact Address

    public class Address : INotifyPropertyChanged
    {
        string m_city;
        public string City
        {
            get { return m_city; }
            set
            {
                m_city = value;
                NotifyPropertyChanged(new PropertyChangedEventArgs("City"));
            }
        }
    }

    public class Contact : INotifyPropertyChanged
    {
        Address m_address;

        public Address Address
        {
            get { return m_address = value; }
            set
            {
                m_address = value;
                NotifyPropertyChanged(new PropertyChangedEventArgs("Address"));
            }
        }
    }

    public class Person : INotifyPropertyChanged
    {
        Contact m_contact;

        public Contact ContactInfo
        {
            get { return m_contact = value; }
            set
            {
                m_contact = value;
                NotifyPropertyChanged(new PropertyChangedEventArgs("ContactInfo"));
            }
        }
    }

I have a person User control that contains a contact user control. When I change the city it calls notifyPropertychanged of the city property at the address class. and It doesn't call neither the Address setter under Contact class nor Contact setter under Person class. How can I notify the person class when the city property changed???

Community
  • 1
  • 1
sayed saad
  • 672
  • 7
  • 12
  • Take a look at this http://stackoverflow.com/questions/7577332/nested-inotifypropertychanged-class-wont-work – Tomislav Markovski Dec 22 '11 at 20:18
  • Shameless plug: MadProps has [propogation built-in](http://code.google.com/p/madprops/#Propogation) as well as no "magic strings" for identifying properties. – default.kramer Dec 22 '11 at 22:17

1 Answers1

0

The other classes will have to register to the Address's PropertyChanged event if they're interested in using it

For example, Contact will only raise a PropertyChanged event on Address if the object reference gets changed, such as setting Address = new Address() or Address = null. It doesn't care about the Address's properties, and rightly so. If you want it to care about the properties, hook up a PropertyChange event on Address.PropertyChanged to raise the Contact.Address PropertyChange event

public class Contact : INotifyPropertyChanged
{
    Address m_address;

    public Address Address
    {
        get { return m_address = value; }
        set
        {
            // Remove old PropertyChanged notification if it existed
            if (m_address != null)
                m_address.PropertyChanged -= Address_PropertyChanged;

            m_address = value;

            // Add new PropertyChanged notification if it existed
            if (m_address != null)
                m_address.PropertyChanged += Address_PropertyChanged;

            NotifyPropertyChanged(new PropertyChangedEventArgs("Address"));
        }
    }
}


void Address_PropertyChanged(object sender, PropertyChangedEventArgs e)
{
    if (e.PropertyName == "City")
        NotifyPropertyChanged(new PropertyChangedEventArgs("Address"));
}

You'd have to do the same thing with the Person class if you want the event to bubble up to the Person class as well.

Another alternative is to use some kind of messaging system, such as MVVM Light's Messenger, or Microsoft Prism's EventAggregator. With this system, the Address class would broadcast an event whenever City changes, and the Person class would subscribe to these messages and handle them with whatever you want providing the Address that sent the message was equal to Person.Contact.Address

Rachel
  • 130,264
  • 66
  • 304
  • 490
  • Please check the Address property getter. get { return m_address = value; } Now, when I change the city property of the address class. It doesn't call the Address property setter of the contact class. what are we missing here? – sayed saad Jan 03 '12 at 16:30
  • @sayedsaad Changing a property on an object does NOT raise the `PropertyChanged` notification for the object itself, only for the property that got changed. So if `Address.City` got changed, then the `Address` class would raise a `PropertyChanged` event for the `City` property, however `Contact` would NOT raise a `PropertyChanged` event for `Contact.Address` because the `Address` object did not change to a new value. If you want that kind of behavior, then you have to tell `Contact` that it should raise a `PropertyChanged` event whenever `Contact.Address.PropertyChanged` fires – Rachel Jan 03 '12 at 16:44