Question

See EDIT section at the bottom...

In a WPF / MVVM-based application, I have a ViewModel that contains an ObservableCollection of objects. Each of these objects has an enum "Status" member that implements INotifyPropertyChanged.

In the View, I need to display the count of objects in the collection that have a particular "Status". Since each object's status can be updated dynamically, the View needs to reflect those dynamic changes in the displayed values.

Currently, I have a ViewModel property that returns the count of each status (one property for each status). For instance:

public int TranslatedWithErrorsCount
{
    get { return FileCollection.Count(n => n.Status == TranslateStatus.TranslatedWithErrors); }
}

However, since the value of each count property is just a by-product of the current state of the collection (and therefore I don't ever set it), it's not clear to me how to best trigger the chain of events that starts with the change of an object's status and ends with the displayed count values updating dynamically.


* EDIT *

At the time of posting, I already had a working solution. I didn't want to muddy the waters with what I had already done as I assumed there was probably a better way. Anyway, based on the current responses, maybe my existing solution is more acceptable than I expected.

Currently, I:

  1. Subscribe to my collection's CollectionChanged event and in the event handler, I manually fire PropertyChanged events on my "Count" properties.
  2. I based the collection itself on "TrulyObservableCollection" instead of "ObservableCollection" in order to catch individual Status change events in the underlying objects.

This all seems to work as expected, but I assumed there might be a cleaner way.

Was it helpful?

Solution

Attach an eventhandler to FileCollection.CollectionChanged

In EventHandler call RaisePropertyChanged("TranslatedWithErrorsCount") on your ViewModel.

If you want to check if Status property changes... You would have to attach and detach handlers from PropertyChanged of items in CollectionChandged handler. Easiest way to store such handlers is dictionary.

EDIT: Actually that is quite fine way of dealing with those: https://stackoverflow.com/a/8490996/1749204

OTHER TIPS

You could hook up the CollectionChanged on your ObservableCollection and in its event handler hook up changes of the Status (Probably wont compile, but you get the idea):

private void OnPropertyChanged(object sender, NotifyPropertyChangedEventArgs e)
{
    PropertyChanged("TranslatedWithErrorsCount");
}


FileCollection.CollectionChanged += (sender, e) => 
{
    PropertyChanged("TranslatedWithErrorsCount"); 

    if (e.NewItems != null)
    {
        foreach (var item in e.NewItems)
        {
            var inpc = item as INotifyPropertyChanged;

            inpc.PropertyChanged += OnPropertyChanged;
        }
    }

    if (e.OldItems != null)
    {
        foreach (var item in e.OldItems)
        {
            var inpc = item as INotifyPropertyChanged;

            inpc.PropertyChanged += (sender, e) => OnPropertyChanged;
        }
    }
}
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top