tldr:CollectionViewSource.Filter被另一个控件覆盖。我如何有两层过滤,以便控件仅看到预过滤的集合?
我有一个第三方网格控件,该控件通过ICollectionView绑定(bind)到我的 View 模型中的集合。
private CollectionViewSource _filteredCollection;
public ItemListViewModel (List<ItemViewModel> items)
{
_items = items;
_filteredCollection = new CollectionViewSource {Source = _items};
}
public ICollectionView AllInstructions
{
get { return _filteredCollection.View; }
}
这可以正常工作,并允许gridcontrol进行自己的过滤,分组和排序。
现在,我想在网格的过滤器之前应用自己的过滤器(即仅显示当前项目的按钮)
public ItemListViewModel (List<ItemViewModel> items)
{
...
_filteredCollection.Filter += new FilterEventHandler(FilterByDate);
}
private void FilterByDate(object sender, FilterEventArgs e)
{
var item = e.Item as ItemViewModel;
if (item == null)
{
e.Accepted = false;
}
else
{
e.Accepted = item.CreatedDate >= _selectedDate;
}
}
我的新过滤器可以正常工作。
问题是,gridcontrol不能很好地使用它,而只是用自己的覆盖任何过滤器。
我的想法是在_filteredCollection CVS上执行过滤,然后围绕它创建另一个CollectionViewSource或CollectionView,并将其传递给gridcontrol。
如果我将_filteredCollection包装在ICollectionView中,则两层过滤可以完美地工作,但是我无法进行排序或分组,因为ICollectionView的默认构造函数的CanSort和CanGroup设置为false。
我不知道如何将_filteredCollection馈入第二个CollectionViewSource的构造函数中。是否有可能或者我从错误的角度来解决这个问题?
最佳答案
您可以通过从ListCollectionView派生预定义的过滤器来创建自己的集合 View ,如以下代码所示:
class FilteredListCollectionView : ListCollectionView
{
// internal filter
private Predicate<object> preFilter;
// public filter
private Predicate<object> filter;
public FilteredListCollectionView(IList list)
: base(list)
{
}
private Predicate<object> GetCombinedFilter()
{
if (this.preFilter != null)
return this.filter != null ? x => this.preFilter(x) && this.filter(x) : this.preFilter;
else
return this.filter;
}
public Predicate<object> PreFilter
{
get { return this.preFilter; }
set
{
this.preFilter = value;
base.Filter = this.GetCombinedFilter();
}
}
public override Predicate<object> Filter
{
get { return base.Filter; }
set
{
this.filter = value;
base.Filter = this.GetCombinedFilter();
}
}
}
现在您可以像这样使用它:
private FilteredListCollectionView _filteredCollection;
public ItemListViewModel(List<ItemViewModel> items)
{
_items = items;
_filteredCollection = new FilteredListCollectionView(_items);
_filteredCollection.PreFilter = FilterByDate;
}
public ICollectionView AllInstructions
{
get { return _filteredCollection; }
}
private bool FilterByDate(object obj)
{
var item = obj as ItemViewModel;
if (item == null)
{
return false;
}
else
{
return item.CreatedDate >= _selectedDate;
}
}
我没有用任何控件测试过,但是我认为它应该可以工作。
关于.net - CollectionViewSources是否可嵌套?,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/17569832/