Some properties on my viewmodel:
public ObservableCollection<Task> Tasks { get; set; }
public int Count
{
get { return Tasks.Count; }
}
public int Completed
{
get { return Tasks.Count(t => t.IsComplete); }
}
What’s the best way to update these properties when Tasks changes?
My current method:
public TaskViewModel()
{
Tasks = new ObservableCollection<Task>(repository.LoadTasks());
Tasks.CollectionChanged += (s, e) =>
{
OnPropertyChanged("Count");
OnPropertyChanged("Completed");
};
}
Is there a more elegant way to do this?
With respect to
Count, you don’t have to do this at all. Simply bind toTasks.Countand your bindings will get notified of the change by theObservableCollection.Completedis a different story, because this is outside ofObservableCollection. Still, from the level of the abstraction/interface, you really wantCompletedto be a property of thatTaskscollection.For this, I think a better approach would be to create “sub” view-model for your
Tasksproperty:This gives you all of the benefits of the
ObservableCollection, and effectively makes theCompletedproperty part of it. We still haven’t captured only the cases where the number of completed items truly changes, but we have reduced the number of redundant notifications somewhat.Now the viewmodel just has the property:
…and you can bind to
Tasks,Tasks.Count, andTasks.Completedwith ease.As an alternative, if you would rather create these other properties on the “main” view-model, you can take this notion of a subclassed
ObservableCollection<T>to create one with some method where you can pass in anAction<string>delegate, which would represent raising a property change notification on the main view-model, and some list of property names. This collection could then effectively raise the property change notifications on the view-model:You could even leave the property type as
ObservableCollection<Task>.