Should I bind to ICollectionView or ObservableCollection

42,176

Solution 1

You always bind to an ICollectionView, whether you make it explicit or not.

Assume that we have

var collection = new ObservableCollection<string>();
var collectionView = CollectionViewSource.GetDefaultView(collection);

In this case, binding to collection or to collectionView is one and the same: the binding engine will bind to the default collection view (which is reference equal to collectionView) if you tell it to bind to collection.

This means that the answer to your question is "it makes absolutely no difference".

Just to be totally clear: even if you bind to the collection directly, the binding engine will bind to the default view. Modifying properties of the view such as sort criteria will affect the binding that appears to bind directly to the collection, since behind the covers it's a binding to the default view instead.

However, there is another interesting and related question: should one bind to the default collection view (i.e., to the collection itself, because there's no reason to explicitly bind to the default view) or to another view of the same collection?

Considering that each view has its own notion of current item, sort criteria, etc, it follows that if you intend to have multiple bindings to the same collection, and the bound controls need to have distinct notions of current item, filters and company, then what you want is to explicitly bind to multiple views of the same underlying collection.

Solution 2

ObservableCollection<T> implements INotifyCollectionChanged and will notify the UI when the items in the collection have been changed.

ICollectionView will give you the ability to filter, sort, or group the collection in addition to propogating INotifyCollectionChanged events if the underlying collection implements it.

Either type works well with MVVM as long as you bind to it. Use ICollectionView when you need sorting, filtering, or grouping. Use ObservableCollection<T> directly when you don't.

Solution 3

Just to add to what Jon said. The main difference is, that by using CollectionViewSource.GetDefaultView(collection), you are making you ViewModel dependent on WPF. Many MVVM purists don't like this and this would leave ObservableCollection only valid option.

Other option would be to use ICollectionView and use a class, that implement it, but is not part of WPF itself.

Solution 4

I don't think so it has to do anything with MVVM itself. ICollectionView provides additional features like soring grouping and etc if you need those use IColectionView otherwise simply use ObservableCollection

Solution 5

You would bind to the view if you wish your grid to display the settings applied to the view, e.g. filtering, otherwise the view is redundant.

Share:
42,176
Cartesius00
Author by

Cartesius00

Fun

Updated on July 08, 2022

Comments

  • Cartesius00
    Cartesius00 almost 2 years

    Should one bind DataGrid to the

    ICollectionView = CollectionViewSource.GetDefaultView(collection)

    or to the

    ObservableCollection<T> collection; ???

    What is the best practice for MVVM and why?

  • Berryl
    Berryl almost 13 years
    Awesome answer. My own preference is to bind to the ObservableCollection now that it is part of System.Collections and "feels" more representative of something I am representing about the Model as opposed to the View, but MVVM is touchy feely this way sometimes.
  • jspaey
    jspaey over 11 years
    Greate answer. I'd just like to point out that in Silverlight a default CollectionView will not be created for bound collections unless that bound collection implements ICollectionViewFactory.
  • Dirk Bester
    Dirk Bester almost 10 years
    That is not the main difference though. Note the wpf tag. "[if] the bound controls need to have distinct notions of current item, filters and company, then what you want is to explicitly bind to multiple views of the same underlying collection". That is the difference. Being a "purist", whatever that is, means you can not filter etc. See the Jimmie Houts answer which focuses on the actual difference in clearer language.
  • Robert MacLean
    Robert MacLean over 9 years
    Is this also/still applicable to Universal apps?
  • Waihon Yew
    Waihon Yew over 9 years
    @RobertMacLean: I don't have any WP development experience so unfortunately no idea.
  • Frank Liu
    Frank Liu over 9 years
    To create an explicit view for a underlying collection in xaml, create a CollectionViewSource element in the Resources. Having the CollectionViewSource.Source property bond to the underlying collection. Then bind your ItemsControl.ItemSource property to the CollectionViewSource you created in the resource via StaticResource. This way, sorting/filter/grouping operation applied to one view wont "contaminate" other ItemsControls that are binding to the Default CollectionView.
  • Muds
    Muds over 8 years
    CollectionViewSource.GetDefaultView(myObservableCollection) gives me original collection back not filtered, what could be it ?
  • Waihon Yew
    Waihon Yew over 8 years
    @Muds no idea without the context. Perhaps ask a new question referencing this one and showing the relevant code/XAML you have?
  • Muds
    Muds over 8 years
    true, I will do that now! thanks Jon... be active there :)
  • Daniel
    Daniel over 4 years
    Investigating what seemed to be a bug in my application, I came away with some information that seems to somewhat conflict with, or expand on, this answer. GetDefaultView or binding directly to ObservableCollection not cause controls to share CurrentItem; however, if you create your own ListCollectionView, any bound controls will share CurrentItem. This is strange as GetDefaultView itself returns a ListCollectionView, which appears to have no options for configuring the behavior of CurrentItem.
  • StayOnTarget
    StayOnTarget almost 4 years
    This other post seems to contradict that ICollectionView will automatically get updated based on a collection changed event... is it incorrect? stackoverflow.com/a/17906474/3195477
  • Jimmie R. Houts
    Jimmie R. Houts almost 4 years
    @UuDdLrLrSs if the items in the collection are modified, the UI that is bound to those items, or properties of those items, will update without the need to call Refresh on the collection. The other post is specifically asking about changing properties of items in the collection and automatically triggering a refresh of the ICollectionView to ensure it only includes items that still match the filter criteria. Based on the answer in the other post, you would have to call the Refresh() method to update the "list" of items in the collection.