Updating UI Bound to Dependant Properties

47 views Asked by At

I have several properties that return values dependent on another property's value. What is the best way to update the UI bound to a dependent property? See example below, how would you update a UI element bound to the TotalQuantity property of the Parent object when a Quantity in the Children collection changes?

public class Child : INotifyPropertyChanged
{
    private int quantity;

    public int Quantity
    {
        get
        {
            return quantity;
        }
        set
        {
            quantity = value;
            OnPropertyChanged("Quantity");
        }
    }

    public event PropertyChangedEventHandler PropertyChanged;

    protected virtual void OnPropertyChanged(string propertyName)
    {
        this.VerifyPropertyName(propertyName);

        if (this.PropertyChanged != null)
        {
            var e = new PropertyChangedEventArgs(propertyName);
            this.PropertyChanged(this, e);
        }
    }
}

public class ParentObject : INotifyPropertyChanged
{
    private ObservableCollection<Child> children;

    public ObservableCollection<Child> Children
    {
        get
        {
            return children;
        }
        set
        {
            children = value;
            OnPropertyChanged("Children");
        }
    }

    public int TotalQuantity
    {
        get
        {
            return Children.Sum(c => c.Quantity);
        }
    }


    public event PropertyChangedEventHandler PropertyChanged;

    protected virtual void OnPropertyChanged(string propertyName)
    {
        this.VerifyPropertyName(propertyName);

        if (this.PropertyChanged != null)
        {
            var e = new PropertyChangedEventArgs(propertyName);
            this.PropertyChanged(this, e);
        }
    }
}
1

There are 1 answers

1
Mike Eason On

When you instantiate your ObservableCollection, you need to subscribe to the CollectionChanged event.

Children.CollectionChanged += Children_CollectionChanged;

This will be called when an item is added/removed from the collection. You simply need to notify that TotalQuantity has changed.

void Children_CollectionChanged(object sender, System.Collections.Specialized.NotifyCollectionChangedEventArgs e)
{
    OnPropertyChanged("TotalQuantity");
}

In the case where you need to update the TotalQuantity property on the UI whenever a child changes, then you simply need to subscribe to the child's PropertyChanged event.

So, when you add an item to the collection, subscribe to the event:

Child myChild = new Child(); //Just an example, but you get the idea
myChild.PropertyChanged += myChild_PropertyChanged;

And in your event handler, you can test to see what property has changed.

void myChild_PropertyChanged(object sender, System.ComponentModel.PropertyChangedEventArgs e)
{
    if (e.PropertyName == "Quantity")
       OnPropertyChanged("TotalQuantity");
}

Or, you could just call OnPropertyChanged without checking if you're a badass. But I wouldn't recommend it just in case your model gains more properties in future.

Don't forget to unsubscribe the event before you remove the child from the collection.