views:

382

answers:

2

Is there a way to get notified when CompositeCollection's current location changes?

I need to have the CompositeCollection monitored by a CollectionView, any ideas are welcommed.

+1  A: 

You can detect when the current item has changed by monitoring the ICollectionView.CurrentChanged event of your CollectionView. The following code works for me:

CompositeCollection cc = new CompositeCollection();
cc.Add(new CollectionContainer { Collection = new string[] { "Oh No!", "Fie" } });
cc.Add(new CollectionContainer { Collection = new string[] { "Zounds", "Ods Bodikins" } });
CollectionViewSource cvs = new CollectionViewSource { Source = cc };

// Subscribing to CurrentChanged on the ICollectionView
cvs.View.CurrentChanged += (o, e) => MessageBox.Show("current changed");

lb.ItemsSource = cvs.View;  // lb is a ListBox with IsSynchronizedWithCurrentItem="True"

When I change the selection in the ListBox, the message box displays.

Regarding filtering, sorting and grouping, as per Aron's answer these are not available on a view over a CompositeCollection. But for the record here are the ways you can detect changes for views that do support these features:

  • It looks like you'll get a CollectionChanged event when the filter changes, though I can't find this documented.
  • SortDescriptions is SortDescriptionCollection which is INotifyCollectionChanged, so hook up a CollectionChanged event handler on the SortDescriptions property.
  • GroupDescriptions is ObservableCollection<GroupDescription>, so hook up a CollectionChanged event handler on the GroupDescriptions property.
itowlson
The problem is I am using CompositeCollection that is bound to two different CollectionViewSource objects.When I changed the location in the ListBox (which IsSynchronizedWithCurrentItem is obviously set to True) the CurrentChanging(ed) is not fired.
Shimmy
So you have two CVSes over the same collection? Dumb question, but are you sure you're subscribing to the event on the correct CVS.View? Suggest you update the question to show the code that isn't working.
itowlson
Maybe you tell me how to do it. Desired is CurrentChanging should be monitored. Conclusion from all my attempts is, The event is not fired. this is not a dumb questin, I think it's more complicated than it is; I wish it's not.
Shimmy
Sorry, I meant my question ("are you sure you're subscribing to the event on the correct CVS view?") was a dumb "sanity check" question. I don't think your original question is dumb, and didn't meant to suggest that.
itowlson
oh np thanks.anyway, i think im subscribing to the right CVS, I even created a test CVS that its Source is the CompositeCollection, and I don't get notified, have you ever been into this situation? any example would be appreciated.Thanks for all your effort!BTW, I checked your blog, there is amazing stuff overthere!
Shimmy
u tha king!!!!!
Shimmy
BTW, I am assuming if I add items to these collection, the CompositeCollection grows as well right? orelse the CompositeCollection only knows about 'objects' added to it, not collections.
Shimmy
If the underlying collection that you add to is INotifyCollectionChanged, then yes, the CompositeCollection will pick up the change (and you will see the new item in the ListBox). In my sample, I was using string[] so this **WON'T** work. (Of course, you can't add elements to arrays anyway... but you know what I mean.) If I change my code to use `ObservableCollection<string>`, then adding to one of the ObservableCollections causes the composite ListBox to update.
itowlson
Is there a way to sort and filter the CompositeCollection? Any outabox/workaround?
Shimmy
A: 

You cant run a CollectionView on a copmposite collection, see here

Aran Mulholland
The sorting and filtering is less important for me. Top priority is CurrentChanging.BTW take a look at my discussion with itowlson above, he says he's soon going to post code. let's hope for godies...
Shimmy
You can, because that's how currency works -- hadn't realised the limitations though -- thanks!
itowlson