WPF在同一个ListCollectionView上使用多个过滤器 [英] WPF Using multiple filters on the same ListCollectionView

查看:249
本文介绍了WPF在同一个ListCollectionView上使用多个过滤器的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我使用MVVM设计模式,将ListView绑定到ViewModel上的ListCollectionView。我也有几个组合框用于过滤ListView。当用户从组合框中选择一个项目时,ListView将被筛选为所选项目。每当我想过滤已经过滤的东西时,它就会解除我以前的过滤器,就像它从未发生过的那样。移除过滤器也是如此。为一个组合框移除过滤器将删除所有过滤器并显示原始列表。是否有可能在同一个ListCollectionView上有多个独立的过滤器?

我做错了什么,还是这个不支持?你可以找到我的应用程序的屏幕截图这里看我是什么试图完成。这是我过滤的代码...

  ///< summary> 
///过滤列表
///< / summary>
///< param name =filter>标准和项目过滤列表< / param>
[MediatorMessageSink(FilterList,ParameterType = typeof(FilterItem))]
public void FilterList(FilterItem filter)
{
//确保列表可以过滤.. 。
if(Products.CanFilter)
{
//现在过滤列表
Products.Filter =委托(object obj)
{
产品产品= obj作为产品;

//确保有一个对象
if(product!= null)
{
bool isFiltered = false;
switch(filter.FilterItemName)
{
caseCategory:
isFiltered =(product.Category.IndexOf(filter.Criteria,StringComparison.CurrentCultureIgnoreCase))!= -1 ?真假;
break;

caseClothingType:
isFiltered =(product.ClothingType.IndexOf(filter.Criteria,StringComparison.CurrentCultureIgnoreCase))!= -1?真假;
break;

caseProductName:
isFiltered =(product.ProductName.IndexOf(filter.Criteria,StringComparison.CurrentCultureIgnoreCase))!= -1?真假;
break;

默认值:
break;
}

return isFiltered;
}
else
return false;
};


$ / code $ / pre

解决方案

当你设置过滤器属性你重置之前的过滤器。这是事实。现在你怎么能有多个过滤器?如您所知,有两种方法可以进行过滤: CollectionView CollectionViewSource $ b / code>。在第一个使用 CollectionView 的情况下,我们使用委托进行过滤,并且执行多个过滤器,我将创建一个类来聚合自定义过滤器,然后逐个为每个过滤器项调用它们。如下面的代码所示:

  public class GroupFilter 
{
private List< Predicate< object>> ; _filters;

公共谓词< object>过滤器{get; private);}

public GroupFilter()
{
_filters = new List< Predicate< object>>();
Filter = InternalFilter;

$ b $ private bool InternalFilter(object o)
{
foreach(var filter in _filters)
{
if(!filter( o))
{
return false;
}
}

return true;

$ b $ public void AddFilter(Predicate< object> filter)
{
_filters.Add(filter);

$ b $ public void RemoveFilter(Predicate< object> filter)
{
if(_filters.Contains(filter))
{
_filters.Remove(过滤器);
}
}
}

//某处稍后:
GroupFilter gf = new GroupFilter();
gf.AddFilter(filter1);
listCollectionView.Filter = gf.Filter;

刷新过滤的视图可以调用 ListCollectionView.Refresh() 方法。

第二种情况下,使用 CollectionViewSource c>过滤事件来过滤集合。您可以创建多个事件处理程序,按照不同的标准进行过滤。要了解更多关于这种方法请查看Bea Stollnitz的这篇精彩的文章:如何应用多个过滤器?



希望这有助于。

干杯,Anvaka


I'm using the MVVM design pattern, with a ListView bound to a ListCollectionView on the ViewModel. I also have several comboboxes that are used to filter the ListView. When the user selects an item from the combobox, the ListView is filtered for the selected item. Whenever I want to filter on top of what is already filtered, it undoes my previous filter like it never happened. The same is also true for removing a filter. Removing a filter for one combobox removes all filters and displays the original list. Is it possible to have multiple, separate filters on the same ListCollectionView?

Am I doing something wrong, or is this simply not supported? You can find a screen capture of my application here to see what I am trying to accomplish. Here's my code for filtering...

    /// <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;
            };
        }
    }

解决方案

Every time you set Filter property you reset previous filter. This is a fact. Now how can you have multiple filters?

As you know, there are two ways to do filtering: CollectionView and CollectionViewSource. In the first case with CollectionView we filter with delegate, and to do multiple filters I'd create a class to aggregate custom filters and then call them one by one for each filter item. Like in the following code:

  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;

To refresh filtered view you can make a call to ListCollectionView.Refresh() method.

And in the second case with CollectionViewSource you use Filter event to filter collection. You can create multiple event handlers to filter by different criteria. To read more about this approach check this wonderful article by Bea Stollnitz: How do I apply more than one filter?

Hope this helps.

Cheers, Anvaka.

这篇关于WPF在同一个ListCollectionView上使用多个过滤器的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆