使用ICollectionView多次过滤集合

时间:2011-09-23 07:18:17

标签: c# wpf filter icollectionview collectionview

我正在尝试过滤DataGrid中显示的ObservableCollection。 这在第一次工作得很好,但是当我尝试再次过滤时,它使用sourcecollection而不是过滤结果。 简短代码示例:

ICollectionView view = CollectionViewSource.GetDefaultView(myCollection);
view.Filter = delegate(object item){
  User user = item as User;
  if(user != null && user.Name.ToLower().Contains(textbox.Text.ToLower())) return true;
  return false;
};

所以我想要做的只是过滤我的DataGrid中显示的项目,而不是整个集合(当然第一次使用过滤器时,它将使用整个集合)。

4 个答案:

答案 0 :(得分:5)

另一个选择是......

public void cmbYourComboBox_SelectionChanged(object sender, RoutedEventArgs e)
{
    ICollectionView filteredView = CollectionViewSource.GetDefaultView(collection);

    filteredView.Filter = new Predicate<object>(GetFilteredView);

    dgYourDataGrid.ItemsSource = filteredView;
}

public bool GetFilteredView(object sourceObject)
{
    if (HasConditionOne(sourceObject) && HasConditionTwo(sourceObject)
    {
        return true;
    }
    return false;
}

public bool HasConditionOne(object sourceObject)
{
    //perform your test and evaluate the outcome
}

public bool HasConditionTwo(object sourceObject)
{
    //perform your test and evaluate the outcome
}

如果源对象满足所有必需条件,则认为适合在过滤视图中显示。

答案 1 :(得分:0)

其他内容(可能DataGrid)可能正在重置您视图上的过滤器,因为您正在使用共享的默认视图。请改用您自己的集合视图:

ICollectionView view = new ListCollectionView(myList);

答案 2 :(得分:0)

您可以创建一个帮助方法,检查您是否已在集合上设置过滤器,如果已经设置过,则将过滤后的列表保存在视图中并再次过滤它并将视图设置为DataGrid的数据源。

ICollectionView view = CollectionViewSource.GetDefaultView(myCollection);

我认为这部分代码总是为您提供整个集合,而不是已经过滤的代码。

答案 3 :(得分:0)

您应该修复的真正的问题是CollectionView过滤器的性能,而不是通过将新过滤的列表作为源集合反馈到下一个过滤器来实现嵌套过滤器。

您“想要”的嵌套过滤器/反馈源收集方法会在用户执行多次键入和删除字符的尝试时导致问题,因为这样您就无法确定哪个源集合适用于该过滤器文本。

E.g。我们有100名员工,我们通过输入“员工姓名”作为“A”来过滤它...这列出了50名名字以“A”开头的员工。现在我们继续输入“H”......来自那些名字以“AH”开头的50名员工被过滤掉了。但是现在我们删除“H”,理想情况下应该使用100名员工来搜索新的员工列表,但它会使用10名员工,因为这会反馈到嵌套的过滤流程。

想象一下,如果有人经常输入并从过滤后的文字中删除随机字符,会有多复杂!

所以基本规则是您必须在整个源集合中过滤

现在我们知道了这一点,我们可以尝试改进过滤功能...

  1. 使用LINQ并将结果设置为每个键入字符的DataGrid的ItemsSource。它们适用于大型集合(我有一个这样的数据网格有30万行,我使用LINQ执行快速过滤)。

  2. LINQ可以在后台线程上运行,并将结果重新应用于datagrid的ItemsSource。

  3. 如果在.Net 4.0中,LINQ提供AsParallel()调用。非常有效。使用有限数量的池化线程进行过滤。

  4. LINQ还为基于字符串属性名称的搜索提供了AsQueryable()接口。