Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How do I update an IValueConverter on CollectionChanged?

Here's a basic example to explain my problem. Let's say I have

ObservableCollection<int> Numbers {get; set;}

and an IValueConverter that returns the sum of Numbers.

Normally what I'd do is changed the IValueConverter into an IMultiValueConverter and bind a second value to Numbers.Count like this

<MultiBinding Converter="{StaticResource SumTheIntegersConverter}">
    <Binding Path="Numbers"     />
    <Binding Path="Numbers.Count"   />
</MultiBinding>

However I'm unable to use this method to solve my actual problem. It seems like there should be a better way to update the binding when the collection changes that I'm just not thinking of. What's the best way to get the value converter to run when items are added and removed to Numbers?

like image 441
Bryan Anderson Avatar asked Nov 04 '09 17:11

Bryan Anderson


2 Answers

This is actually surprisingly very difficult. An IValueConverter doesn't update, so this does not work as you'd hope.

I wrote a sample on the Microsoft Expression Gallery called Collection Aggregator that shows a working, if convoluted, approach to making this work via a Behavior that does the aggregation (Count, in your case, although I also support Sum, Average, etc) for you, instead of a converter.

like image 127
Reed Copsey Avatar answered Sep 27 '22 17:09

Reed Copsey


In your model, subscribe to CollectionChanged and raise PropertyChanged:

Numbers.CollectionChanged += (o,e) => 
  OnPropertyChanged(new PropertyChangedEventArgs(nameof(Numbers)));

And, as thomasgalliker mentioned, you should unsubscribe from the event when the model containing the connection is no longer used.

like image 38
Michael Avatar answered Sep 27 '22 17:09

Michael