Question

My questions is similar to this INotifyPropertyChanged and calculated property

I'm reusing some code from the above example because it's easier to understand what's going on.

Assume I started with something similar to this. Note that INotifyPropertyChangedBase is the base class that I use to implement INotifyPropertyChanged.

public class Order : INotifyPropertyChangedBase
{
  private string itemName;
  public string ItemName 
  { 
    get { return itemName; }
    set 
    {
       itemName = value;
    }
  }

  private decimal itemPrice;
  public decimal ItemPrice 
  { 
    get { return itemPrice; }
    set 
    {
       itemPrice = value;
    }
  }

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

  public decimal TotalPrice
  {
    get { return ItemPrice * Quantity; }    
  }
}

After generating similar code to this I realized that each order could be comprised of multiple Items so I generated a class : Item similar to this:

public class Item : INotifyPropertyChangedBase
{
  private string name;
  public string Name
  {
    get { return name; }
    set { name = value; }
  }

  private decimal price;
  public decimal Price
  {
    get { return price; }
    set { price = value; }
  }

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

Then I converted my Order class to look like this.

public class Order : INotifyPropertyChangedBase
{
  private ObservableCollection<Item> itemInfo;
  public ObservableCollection<Item> ItemInfo 
  { 
    get { return itemInfo; }
    set 
    {
       itemInfo = value;
       OnPropertyChanged("ItemInfo");
       OnPropertyChanged("TotalPrice");
    }
  }

  public decimal TotalPrice
  {
    get 
    { 
      Decimal totalPrice;
      foreach (Item item in ItemInfo)
      {
        totalPrice += item.Quantity * item.Price;
      }
      return totalPrice;
    }    
  }
}

Implementing this is done via a DataGrid. Each Order is a row. I am binding column headers to Item.Name (limited number of options) and Item.Quantity to the appropriate column cell. The final column is the TotalPrice.

Previously, the TotalPrice would update when I changed the Quantity. Now, with the new implementation using Item the TotalPrice will not update in the DataGrid. It seems that the setter for ItemInfo will not fire when I update a instance of Item.Quantity. The setter on Item.Quantity does fire when I update the appropriate DataGrid cell.

How do I get the value of a read-only property (TotalPrice) to update using nested properties (Item)?

Was it helpful?

Solution

You will have to listen CollectionChanged of ItemInfo like

public class Order : INotifyPropertyChangedBase
{
   public Order()
   {  
    ItemInfo =new ObservableCollection<Item>();
    ItemInfo.CollectionChanged += ItemInfo_CollectionChanged;

    }

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

   private ObservableCollection<Item> itemInfo;
   public ObservableCollection<Item> ItemInfo 
   { 
     get { return itemInfo; }
     set 
     {
         itemInfo = value;
         OnPropertyChanged("ItemInfo");
         OnPropertyChanged("TotalPrice");
}

}

OR

public class Order : INotifyPropertyChangedBase
{

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

   private ObservableCollection<Item> itemInfo;
   public ObservableCollection<Item> ItemInfo 
   { 
     get { return itemInfo; }
     set 
     {
         if(itemInfo!=null)
             itemInfo.CollectionChanged -= ItemInfo_CollectionChanged;

         itemInfo = value;

         if(itemInfo!=null)
             itemInfo.CollectionChanged += ItemInfo_CollectionChanged;

         OnPropertyChanged("ItemInfo");
         OnPropertyChanged("TotalPrice");
}

}

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top