views:

35

answers:

2

I bind a collection ObservableCollection<Foo> to a dependency property on my controller, but I run it through an IValueConverter to make it ObservableCollection<object> instead, which is what my controller expect. The conversion works fine - I create an ObservableCollection<object> and fill it with all the Foo's from the original list. This however brings a problem which is that now I'm observing on the collection created in the value converter, and hence doesn't see any of the changes to the original collection.

So; do I have to hook up eventhandlers in the converter to manually keep the converted collection in sync with the original one, or is there a better way to handle this? I guess I can't do the convertion without actually creating a new collection? Or can I do the binding in some clever way such that I don't have to do the convert?

A: 

If i understand correctly you are binding some sort of ICollection that does not implement INotifyCollectionChanged through a converter that creates a new ObservableCollection. In that case you would not get any benefit from the now disconnected collection. Is it possible to bind your collection directly (without converting) and implementing INotifyPropertyChanged and/or INotifyCollectionChanged directly on your object?

MrDosu
I'm sorry if the question was unclear - some parts of the code wasn't showing, but I added code blocks now. I am binding An ObservableCollection to an ObservableCollection-property. The problem is the type of elements, which is why I have to add a converter (or is there a better way?). In the converter a new collection is created, making me loose the observing of the original one. The question is how to best keep observing the original one. Can I add a more clever binding? Or do I need to keep them in sync manually.
stiank81
+1  A: 

I don't know if it helps, but often in a ViewModel, I declare IList or another less specific interface as the property type instead of a specific one.

Then I can bind quasi all collections and lists to this propery.

While the property is set, I check if it Implements INotifyPropertyChanged and if yes, I attach an CollectionChanged-EventHandler. When the property has changed newly, I remove the EventHandler from the old INotifyPropertyChanged (if it was).

The drawback of this is, that the ViewModel must be prepared to see objects other types than expected. But this is normally a simple job.

void YourDPValueChanged(DependencyPropertyChangedEventArgs e) {
    INotifyCollectionChanged newCollection = e.NewValue as INotifyCollectionChanged;
    INotifyCollectionChanged oldCollection = e.OldValue as INotifyCollectionChanged;
    if (null != newCollection) {
        newCollection.CollectionChanged += new NotifyCollectionChangedEventHandler(Collection_CollectionChanged);
    }
    if (null != oldCollection) {
        oldCollection.CollectionChanged -= new NotifyCollectionChangedEventHandler(Collection_CollectionChanged);
    }
HCL
Thx for your attention. I tried that, but it doesn't seem to help me. I normally use IList too, but I believe the problem is the type of objects the list holds. I hoped that a list of object can have a list of anything bound to it, but the dependency property is only triggered if I bind a collection of the exact same type to it - also when using IList..
stiank81
@stiank81: This looks as it is a problem with the Binding: ObservableCollection<T> implements Collection<T> and this implements IList. Therefore it can not be a problem of the contained type. Do I understand the initial design right: Your ViewModel has this IList-property and you bind from your View an ObservableCollection<T> to it. Right?
HCL
My ViewModel has an ObservableCollection<Foo>, and in my view I have a control with property ObservableCollection<object> which I bind the ObservableCollection<Foo> to. The binding isn't applied due to the type mismatch, and it seems like I have to change one of them to get a match in the binding. That's what I tried solving using an IValueConverter, but then I get an extra collection in between which means I loose track of the original ObservableCollection in me ViewModel.
stiank81
@stiank81: Ok, in this case, if you don't want to change the ViewModel's property to a IList or IEnumerable, I think you have to write a converter that makes the conversion and also connects the source-and the destination-collection for CollectionChanged-events. Another idea could be to add a second property in your ViewModel that has the same purpose as the specific one but supports IList? This makes the VM a little bit more complex but then you have both options, a strongly typed and a generic one.
HCL
Yeah, seems like this will be the solution.. Have considered adding a generic list to my ViewModel, but I don't think I'd like to do that.. Thanks for your input on this!
stiank81