Bre*_*ent 12 wpf filter listcollectionview
我正在使用MVVM设计模式,ListView绑定到ViewModel上的ListCollectionView.我还有几个用于过滤ListView的组合框.当用户从组合框中选择项目时,将针对所选项目筛选ListView.每当我想要在已经过滤的内容之上进行过滤时,它就像从未发生的那样撤消我以前的过滤器.删除过滤器也是如此.删除一个组合框的过滤器将删除所有过滤器并显示原始列表.是否可以在同一个ListCollectionView上拥有多个独立的过滤器?
我做错了什么,或者这根本不受支持?你可以在这里找到我的应用程序的屏幕截图,看看我想要完成什么.这是我的过滤代码......
/// <summary>
/// Filter the list
/// </summary>
/// <param name="filter">Criteria and Item to filter the list</param>
[MediatorMessageSink("FilterList", ParameterType = typeof(FilterItem))]
public void FilterList(FilterItem filter)
{
// Make sure the list can be filtered...
if (Products.CanFilter)
{
// Now filter the list
Products.Filter = delegate(object obj)
{
Product product = obj as Product;
// Make sure there is an object
if (product != null)
{
bool isFiltered = false;
switch (filter.FilterItemName)
{
case "Category":
isFiltered = (product.Category.IndexOf(filter.Criteria, StringComparison.CurrentCultureIgnoreCase)) != -1 ? true : false;
break;
case "ClothingType":
isFiltered = (product.ClothingType.IndexOf(filter.Criteria, StringComparison.CurrentCultureIgnoreCase)) != -1 ? true : false;
break;
case "ProductName":
isFiltered = (product.ProductName.IndexOf(filter.Criteria, StringComparison.CurrentCultureIgnoreCase)) != -1 ? true : false;
break;
default:
break;
}
return isFiltered;
}
else
return false;
};
}
}
Run Code Online (Sandbox Code Playgroud)
Anv*_*aka 26
每次设置Filter属性时,都会重置上一个过滤器.这是事实.现在你怎么能有多个过滤器?
如您所知,有两种方法可以进行过滤:CollectionView
和CollectionViewSource
.在第一种情况下CollectionView
我们使用委托进行过滤,并且要做多个过滤器,我会创建一个类来聚合自定义过滤器,然后逐个为每个过滤器项调用它们.如下面的代码所示:
public class GroupFilter
{
private List<Predicate<object>> _filters;
public Predicate<object> Filter {get; private set;}
public GroupFilter()
{
_filters = new List<Predicate<object>>();
Filter = InternalFilter;
}
private bool InternalFilter(object o)
{
foreach(var filter in _filters)
{
if (!filter(o))
{
return false;
}
}
return true;
}
public void AddFilter(Predicate<object> filter)
{
_filters.Add(filter);
}
public void RemoveFilter(Predicate<object> filter)
{
if (_filters.Contains(filter))
{
_filters.Remove(filter);
}
}
}
// Somewhere later:
GroupFilter gf = new GroupFilter();
gf.AddFilter(filter1);
listCollectionView.Filter = gf.Filter;
Run Code Online (Sandbox Code Playgroud)
要刷新筛选视图,您可以调用ListCollectionView.Refresh()
方法.
在第二种情况下,CollectionViewSource
您使用Filter
事件来过滤集合.您可以创建多个事件处理程序以按不同条件进行筛选.要了解有关此方法的更多信息,请查看Bea Stollnitz撰写的这篇精彩文章:如何应用多个过滤器?
希望这可以帮助.
干杯,安瓦卡.
每次用户过滤时,您的代码都会使用新的代码替换Filter
集合视图中的委托.而且,新的只检查用户刚刚选择的特定标准ComboBox
.
你想要的是一个检查所有标准的过滤器处理程序.就像是:
public MyViewModel()
{
products = new ObservableCollection<Product>();
productsView = new ListCollectionView(products);
productsView.Filter += FilterProduct;
}
public Item SelectedItem
{
//get,set omitted. set needs to invalidate filter with refresh call
}
public Type SelectedType
{
//get,set omitted. set needs to invalidate filter with refresh call
}
public Category SelectedCategory
{
//get,set omitted. set needs to invalidate filter with refresh call
}
public ICollection<Product> FilteredProducts
{
get { return productsView; }
}
private bool FilterProduct(object o)
{
var product = o as Product;
if (product == null)
{
return false;
}
if (SelectedItem != null)
{
// filter according to selected item
}
if (SelectedType != null)
{
// filter according to selected type
}
if (SelectedCategory != null)
{
// filter according to selected category
}
return true;
}
Run Code Online (Sandbox Code Playgroud)
您的视图现在可以绑定到适当的属性,过滤将起作用.
归档时间: |
|
查看次数: |
14297 次 |
最近记录: |