Updating a View Model from Inside a Collection

September 27, 2014

My last post suggested a concept of having a `Selectable` Model, which effectively wraps a model in a class with a generic item and an `IsSelected` property. This does, however, present a slight issue. What if you want to update the view model, based on the item being selected, or de-selected?

Say, for example, that from my previous post, you had a property on the Person class called Wages, and wanted to display the total wages of all the selected people. You would have defined `TotalCostSummary` in the ViewModel, and bound it in the View.

My solution is to pass a delegate into the Selectable item. Here’s how I did it (this doesn’t really make any sense without referring back to the first post).

SelectableItem Model

In the `SelectableItem`, define a new property like so:


        private Action \_updateMethod = null;
        public Action IsSelectedChangedMethod
        {
            get { return \_updateMethod; }
            set
            {
                \_updateMethod = value;
            }
        }

And change `IsSelected` to looks like this:


        private bool \_isSelected;
        public bool IsSelected
        {
            get { return \_isSelected; }
            set
            {
                \_isSelected = value;                
                RaisePropertyChanged();
                
                if (\_updateMethod != null)
                    \_updateMethod();
            }
        }

ViewModel


        private void UpdateTotalCost()
        {
            \_summary = SelectablePeople.Where(a => a.IsSelected).Sum(s => s.Item.Wages);
            RaisePropertyChanged(() => TotalCostSummary);
        }

Next, change the code to define the list:


List population = GetPeople();
SelectablePeople = new ObservableCollection\>(population
	.Select(n => new SelectableItem() 
	{ 
		Item = n, IsSelected = false, IsSelectedChangedMethod = (() => UpdateTotalCost())  
	}).ToList());

Conclusion

The net effect is that the changes now made inside the model can bubble up to the ViewModel, but the separation of the two has been maintained.



Profile picture

A blog about one man's journey through code… and some pictures of the Peak District
Twitter

© Paul Michaels 2022