如何用三个ObservableCollection过滤CollectionViewSource?
问题分析
原代码的核心问题是每个过滤条件只匹配了单个实体的Id(比如Serie.Id应该是你最后添加到列表的项),而不是检查当前项是否存在于整个过滤集合中。要实现多条件的“包含”过滤,需要判断当前项的对应Id是否在过滤集合的Id列表内。
修正后的过滤方法
private void CollectionViewSource_Filter(object sender, FilterEventArgs e) { var articolo = e.Item as BLL.Models.ArticoloProduzione; if (articolo == null) { e.Accepted = false; return; } // 系列过滤:集合为空则不过滤,否则检查当前项的系列Id是否在ListaSerie中 bool serieMatch = ListaSerie.Count == 0 || ListaSerie.Any(s => s.Id == articolo.ArticoloSerieProdotto.Serie.Id); // 产品过滤:同理 bool prodottoMatch = ListaProdotti.Count == 0 || ListaProdotti.Any(p => p.Id == articolo.ArticoloSerieProdotto.Prodotto.Id); // 颜色过滤:同理 bool coloreMatch = ListaColori.Count == 0 || ListaColori.Any(c => c.Id == articolo.Colore.Id); // 三个条件都满足才显示 e.Accepted = serieMatch && prodottoMatch && coloreMatch; }
额外优化建议
- 如果过滤集合数据量较大,建议提前将Id存入
HashSet<int>(假设Id为int类型),Contains方法的查询效率比Any更高:
过滤时替换为:// 维护存储Id的HashSet private HashSet<int> _serieIds = new HashSet<int>(); private HashSet<int> _prodottoIds = new HashSet<int>(); private HashSet<int> _coloreIds = new HashSet<int>(); // 监听集合变更事件,更新HashSet并刷新视图 private void ListaSerie_CollectionChanged(object sender, NotifyCollectionChangedEventArgs e) { _serieIds.Clear(); foreach (var serie in ListaSerie) _serieIds.Add(serie.Id); ArticoliProduzioneViewSource.View.Refresh(); } // 同理给ListaProdotti、ListaColori绑定CollectionChanged事件bool serieMatch = ListaSerie.Count == 0 || _serieIds.Contains(articolo.ArticoloSerieProdotto.Serie.Id); - 每次过滤集合(ListaSerie/ListaProdotti/ListaColori)内容变更时,必须调用
ArticoliProduzioneViewSource.View.Refresh()触发视图重新过滤。
内容的提问来源于stack exchange,提问作者1001100 1101111 1110010 110010
相关产品推荐
相关产品推荐

