2

我正在尝试过滤显示在 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

4 回答 4

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
}

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

于 2012-10-20T19:11:53.463 回答
0

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

ICollectionView view = CollectionViewSource.GetDefaultView(myCollection);

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

于 2011-09-23T07:29:32.953 回答
0

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

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

例如,我们有 100 名员工,我们通过将“员工姓名”键入为“A”来过滤它......这列出了 50 名员工的姓名以“A”开头。现在我们继续输入“H”...从这 50 个名字以“AH”开头的雇员中筛选出 10 个。但是现在我们删除“H”,理想情况下它应该使用 100 名员工来搜索新的员工列表,但它将使用 10 名员工,因为这会反馈给嵌套过滤过程。

想象一下,如果有人经常键入并从过滤后的文本中删除随机字符,这将变得多么复杂!

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

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

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

  2. LINQ 可以在后台线程上运行并将结果重新应用到数据网格的 ItemsSource。

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

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

于 2011-09-23T08:56:39.640 回答
0

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

ICollectionView view = new ListCollectionView(myList);
于 2011-09-23T07:22:32.020 回答