How to observe nested objects By having two model classes Conversation and Message, what are the best practices to handle the next situation: A conversation listening for its messages PropertyChanged events and so being able to update itself.


What are the best practices?  
How can I improve this model design?
Is it going to generate memory leaks?


code 

using SoftConsept.Collections;

public class Conversation 
{
    readonly SortedObservableCollection&lt;Message&gt; messages;

    public Conversation ()
    {
        messages = new SortedObservableCollection&lt;Message&gt; ();
    }

    public void Add (Message message)
    {
        messages.Add (message);
        message.PropertyChanged += HandleMessagePropertyChanged;
    }

    public void Remove (Message message)
    {
        message.PropertyChanged -= HandleMessagePropertyChanged;
        messages.Remove (message);
    }

    public IList&lt;Message&gt; Messages ()
    {
        return messages.ToList ();
    }

    void HandleMessagePropertyChanged (object sender, PropertyChangedEventArgs e)
    {
        // Uptade omitted conversations properties using data from the updated message.
    }
}

public class Message : INotifyPropertyChanged 
{
}
First of all, the Conversation class does not provide any events for chances, so nobody has a chance to get to know if something changes. This is already be implemented within an (Sorted)Observable collection, but unfortunately you publish this private field as IList&lt;Message&gt; by the Message method. So the notification abilities of this collection can not be used. Furthermore methods should always be connected with a action, so GetMessages() would be a more suitable name. But the best way is to make it a property.  

using SoftConsept.Collections;

public class Conversation : INotifyPropertyChanged
{
    readonly SortedObservableCollection&lt;Message&gt; messages;

    public event PropertyChangedEventHandler PropertyChanged;

    public Conversation ()
    {
        messages = new SortedObservableCollection&lt;Message&gt; ();
    }

    private DateTime _updateTime = DateTime.Now;
    public DateTime UpdateTime{
       get{ return _updateTime;}
       private set{
           UpdateTime = value;
           OnPropertyChanged("UpdateTime");
       }
    }

    private void OnPropertyChanged(string propertyName){
       var handler = PropertyChanged;
       if(handler==null) return;
       handler(this, new PropertyChangedEventArgs(propertyName));
    }

    public void Add (Message message)
    {
        messages.Add (message);
        UpdateTime = DateTime.Now;
        message.PropertyChanged += OnMessagePropertyChanged;
    }

    private void OnMessagePropertyChanged(object sender, PropertyChangedEventArgs args)
    {
        UpdateTime = DateTime.Now;
    }

    public void Remove (Message message)
    {
        messages.Remove (message);
        UpdateTime = DateTime.Now;
        message.PropertyChanged -= OnMessagePropertyChanged;
    }

    public ObservableCollection&lt;Message&gt; Messages 
    {
        get{ 
            //I assume that SortedObservableCollection is subtype of ObservableCollection
            return messages;
        }
    }
}

public class Message : INotifyPropertyChanged {}


So now some observer might register for changes in Messages (add, delete) and also for changes in the single Message instances. 

For more info, look at Microsoft documentation: