views:

47

answers:

1

I am binding a ListView a property that essentially wraps the Values collection (ICollection) on a generic dictionary.

When the values in the dictionary change, I call OnNotifyPropertyChanged(property). I don't see the updates on the screen, with no binding errors.

When I change the property getter to return the Linq extension dictionary.Values.ToList(), without changing the signature of the property (ICollection) it works with no problem.

Any reason why the Values collection bind and notify properly without projecting to an IList<>?

+2  A: 

Calling OnNotifyPropertyChanged() isn't exactly correct in this case, since the collection is still the same, however the items in the collection have changed. I don't know exactly how the WPF binding code works, but it might do a quick check to see if the reference it is binding to has changed, and if not it won't update the UI.

The reason that ToList() works is because each time it is called, a new instance of List<T> is returned, so when OnNotifyPropertyChanged() is fired, WPF picks up on the change and updates all of its bindings.

I don't know if this is possible or not, but the ideal solution would be to use a collection for bindings that implements INotifyCollectionChanged. This will fire events that WPF monitors so that items can be added, removed, etc. from the UI as appropriate.

Andy
Interesting, although I thought that's what calling PropertyChanged accomplished. In most cases (and in most examples), this is put in the setter, and is called only if the value/reference changed. This is actually exactly the reason I thought my approach would work--I thought the PropertyChanged call caused the update, not the change to the value/reference.
Phil Sandler
There are examples of a dictionary that implements INotifyCollectionChanged out there. Try searching for ObservableDicitonary.
Bryan Anderson
@Phil @Andy is correct in that the WPF binding system checks references as an optimization. If the reference doesn't change it doesn't update the bindings. This is why the INotifyCollectionChanged interface exists.
Bryan Anderson
Again, interesting, and good to know. So the code I use in setters (and see in many examples) like "if (_myVar == value) return;" is only necessary for value types? I guess I'll stick with ToList() for now, as I had all kinds of problems with the ObservableDictionary I tinkered with for a similar screen. Thanks for your comments.
Phil Sandler