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.