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?
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 aCollectionViewSource
object, add your collection to theSource
property, and get the collection view from theView
property.
This approach is the equivalent to CollectionViewSource.GetDefaultView
, i.e. you will use the retrieved View
just the same: