Keep track of user changes

Topics: Prism v4 - Silverlight 4
Mar 16, 2015 at 2:30 PM
Hi,

I am looking for advice on how to best track changes within a composite view in a PRISM application using MVVM.

In my case, I have an OrderViewModel, which in turns has a collection of OrderlineViewModel, which in turn has a collection of ProductViewModel. I want the OrderViewModel to know if any changes has been made by a user in the order at any level in the view model hierarchy. In this case, the save command should be enabled among other things.

I see three alternatives:

1

Subscribe to INotifyPropertyChanged on all view model objects present for the view (and CollectionChanged on all lists). This leads to quite cumbersome code to maintain in the root view model, similar to:
public void Subscribe()
{
  // Listen for changes on OrderViewModel
  this.PropertyChanged -= OnDirty;
  this.PropertyChanged += OnDirty;

  // Listen if order lines added/removed
  this.OrderlineViewModels.CollectionChanged -= this.OnDirty;
  this.OrderlineViewModels.CollectionChanged += this.OnDirty;

  // Listen for changes in any OrderlineViewModel
  {
    foreach (var orderlineViewModel in this.OrderlineViewModels)
    {
      orderlineViewModel.PropertyChanged -= OnDirty;
      orderlineViewModel.PropertyChanged -= OnDirty;
      
      // ... and so on for each level
    }
}

2

Allow all child view models to know about their parent. Then require that all child view models call a method on its parent when a change happened (which will bubble up to the root).
this.PropertyChanged += (s, e) =>
{
  this.Parent.MakeDirty();
};
this.ProductViewModels.CollecitonChanged += (s, e) =>
{
  this.Parent.MakeDirty();
};

3

Use EventAggregator to send out a typed event for each ViewModel, e.g. “OrderlineViewModelChanged”. The root view model needs to subscribe to each event applicable for this view.

Any input on which route to go down, or if we have missed any better approach, is highly appreciated!

Thanks,
Michael