Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How does binding to collections really work?

Well, I'm confused.

If my control has dependency property ItemsSource of IEnumerable type and user binds collection to it what object do I have in DependencyPropertyChangedEventArgs.NewValue?

As far as I know CollectionView is implicitly created for collections and I expect args.NewValue to be of type ICollectionView.

From this blog:

When a user binds a WPF property to a collection of data, WPF automatically creates a view to wrap the collection, and binds the property to the view, not the raw collection. This behavior always happens, and is independent of CollectionViewSource.

But debugger (VS 2012, .net v.4.0) shows me that I receive original raw collection in NewValue. (BindsDirectlyToSource is not set and equals false by default)
How can this be?!

I cannot understand how in this case WPF controls support sorting, grouping and filtering.
How and when is CollectionView injected and used?

like image 212
Pavel Voronin Avatar asked Dec 19 '12 09:12

Pavel Voronin


1 Answers

Maybe the following extract from the Remarks section in CollectionView answers your question:

In WPF applications, all collections have an associated default collection view. Rather than working with the collection directly, the binding engine always accesses the collection through the associated view. To get the default view, use the CollectionViewSource.GetDefaultView method. An internal class based on CollectionView is the default view for collections that implement only IEnumerable. ListCollectionView is the default view for collections that implement IList. BindingListCollectionView is the default view for collections that implement IBindingListView or IBindingList.

Alternatively, you can create a view of your collection in Extensible Application Markup Language (XAML) by using the CollectionViewSource class and then bind your control to that view. The CollectionViewSource class is the XAML representation of the CollectionView class. For an example, see How to: Sort and Group Data Using a View in XAML.

So if you do not explicitly bind to a CollectionViewSource, a collection binding is always made to the original collection (what you get in NewValue), but access to the collection (e.g. get an item by index) is always done through the default view. Therefore the statement "binds the property to the view, not the raw collection" is not exactly true.

A quick test revealed that GetDefaultView returns a System.Windows.Data.ListCollectionView for my bound ObservableCollection.

like image 78
Clemens Avatar answered Oct 11 '22 10:10

Clemens