Search code examples
c#wpfdatagridentityinotifycollectionchanged

Is there a way to trigger some kind of `OnPropertyChanged` event for a computed property that uses a property of a "child entity" in a collection?


Is there a way to trigger some kind of OnPropertyChanged event for a computed property that uses a property of a "child entity" in a collection?

A small example:

I have a simple WPF application with a DataGrid showing Customer properties. I am using Entity Framework 5, CodeFirst approach, so I wrote my classes manually with my own INotifyPropertyChanged implementation.

public partial class Customer : INotifyPropertyChanged
{
    private string _firstName;
    public virtual string FirstName
    {
        get { return _firstName; }
        set
        {
            _firstName = value;
            OnPropertyChanged("FirstName");
            OnPropertyChanged("FullName");
        }
    }

    private string _lastName;
    public virtual string LastName
    {
        get { return _lastName; }
        set
        {
            _lastName = value;
            OnPropertyChanged("LastName");
            OnPropertyChanged("FullName");
        }
    }

    public virtual ICollection<Car> Cars { get; set; }
    public virtual ICollection<Invoice> Invoices { get; set; }

    ...
}

Now in that same class I created 3 computed properties:

    public string FullName
    {
        get { return (FirstName + " " + LastName).Trim(); }
    }

    public int TotalCars
    {
        get
        {
            return Cars.Count();
        }
    }

    public int TotalOpenInvoices
    {
        get
        {
            if (Invoices != null)
                return (from i in Invoices
                        where i.PayedInFull == false
                        select i).Count();
            else return 0;
        }
    }

The FullName is automatically updated in the DataGrid because I'm calling OnPropertyChanged("FullName");

I found an example of the INotifyCollectionChanged implementation that I can probably use to auto update the TotalCars when something is added to or removed from the ICollection: http://www.dotnetfunda.com/articles/article886-change-notification-for-objects-and-collections.aspx

But what is the best approach to trigger the OnPropertyChange("TotalOpenInvoices") when a property (PayedInFull) inside the ICollection (Invoices) changes?

Doing something like OnPropertyChanged("Customer.TotalOpenInvoices"); in the Invoice class doesn't seem to do the trick... :)


Solution

  • Do you have control of what goes inside your collections? If you do, you can create a Parent property on your Invoice object and when it is added to the collection, set the parent to your Customer. Then when PaidInFull gets set, run your Customer.OnPropertyChanged("TotalOpenInvoices") or call a method on the Customer object to recalculate your invoices.

    Enforcing parent-child relationship in C# and .Net