Updating a View Model from Inside a Collection

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<Person> population = GetPeople();
SelectablePeople = new ObservableCollection<SelectableItem<Person>>(population
	.Select(n => new SelectableItem<Person>() 
	{ 
		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.

Leave a Reply

Your email address will not be published. Required fields are marked *