Question

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?

Was it helpful?

Solution

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
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top