Search code examples
c#mvvmmodelscaliburn.micro

Pass value from child model to parent model in MVVM


I am coding an MVVM C# WPF software with 2 models. I am using Caliburn.Micro FYI.

The parent Model :

namespace Expense_Manager.Models
{
   public class Receipt: PropertyChangedBase
   {
      public Receipt()
      {
         Items = new List<Item>();
      }
      public List<Item> Items{ get; set; }
      private double _total;
      public double Total
      {
         get { return _total; }
         set
         {
            _total= value;
            NotifyOfPropertyChange(() => Total);
         }
      }
   }
}

The second model:

namespace Expense_Manager.Models
{
   public class Item: PropertyChangedBase
   {
      public Item()
      { }

      private double _amount;
      public double Amount
      {
         get { return _amount; }
         set
         {
            _amount= value;
            NotifyOfPropertyChange(() => Amount
         }
      }
   }
}

I have simplified the models for the purpose of posting this question.

So my question is: How can I have the Total amount in the parent model calculate itself either by:

  1. adding each value of the Item model everytime it is added to the parent's items list
  2. calculating the sum of each item value once the full list of items is entered in the items list (this would mean that if an item is added at a later date, it would not recalculate itself which I am not too happy about so 1 would prefer to do option 1 above)

Solution

  • Use an ObservableCollection instead of List<> because:

    1. It has a CollectionChanged event which you can use to recalculate the amount each time a new item is added / removed.
    2. It implements the INotifyCollectionChanged so you will have no problem to bind it to different controls.

    This is how you would use you it in your case:

    public Receipt()
    {
        Items = new ObservableCollection<Item>();
        Items.CollectionChanged += Items_CollectionChanged;
    }
    
    private void Items_CollectionChanged(object sender, NotifyCollectionChangedEventArgs e)
    {
        Total = Items.Sum(x => x.Amount);
    }
    
    public ObservableCollection<Item> Items { get; set; }