3

So I'm using WPF in the MVVM way using Caliburn.Micro as a framework.

I have a ViewModel with a ObservableCollection that I need to show twice with different sorting, filtering and grouping.

I'm kind of having a hard time with this supposedly simple action. I normally would do this:

private ICollectionView _datagridCollectionView;
public ICollectionView DatagridCollectionView
{
    get
    {
        if (this._datagridCollectionView == null)
        {
            this._datagridCollectionView = CollectionViewSource.GetDefaultView(this.Items);
            using (this._datagridCollectionView.DeferRefresh())
            {
                this._datagridCollectionView.SortDescriptions.Clear();
                this._datagridCollectionView.SortDescriptions.Add(new SortDescription("SortingProperty", ListSortDirection.Ascending));
            }
        }
        return this._datagridCollectionView;
    }
}

And it works fine, it sorts and it's observable.

So I added the second view the same way:

private ICollectionView _chartCollectionView;
public ICollectionView ChartCollectionView
{
    get
    {
        if (this._chartCollectionView == null)
        {
            this._chartCollectionView = CollectionViewSource.GetDefaultView(this.Items);
            using (this._chartCollectionView.DeferRefresh())
            {
                this._chartCollectionView.Filter = (p) => { return p.IsChartable; };
            }
        }
        return this._chartCollectionView;
    }
}

Now the problem is (likely because I access the default view and thus have the same reference) that all sorting/filtering is done to both views.

So I tried to do new instance of ICollectionView but CollectionView should not be used and ListCollectionView is made for lists and not IEnumarbles so I even if I use the ToList() method the views are no longer Observable.

What would be the proper way to do this?

Ingó Vals
  • 4,788
  • 14
  • 65
  • 113
  • 1
    Have you tried following the suggestion documented in the remarks of the documentation of the `CollectionView` class? *To create a collection view for a collection that only implements `IEnumerable`, create a `CollectionViewSource` object, add your collection to the `Source` property, and get the collection view from the `View` property.* – Daniel Hilgarth May 13 '13 at 11:45
  • @DanielHilgarth Absolutely, but your answer pointed me to the mistake I did there, I bound straight to the CollectionViewSource instead of it's View property, this works great. You wan't to submit this as a answer perhaps? Also when you do it this way do you use the sorting on the CollectionViewSource or it's View property. Filter seems to have to be applied straight to the View property. – Ingó Vals May 13 '13 at 11:58

1 Answers1

2

You should use the approach outlined in the remarks section of the documentation of the CollectionView class:

To create a collection view for a collection that only implements IEnumerable, create a CollectionViewSource object, add your collection to the Source property, and get the collection view from the View property.

This approach is the equivalent to CollectionViewSource.GetDefaultView, i.e. you will use the retrieved View just the same:

  • You bind it to the UI
  • You use it to filter
  • You use it to sort
Daniel Hilgarth
  • 171,043
  • 40
  • 335
  • 443