.NET 6是否支持ICollectionView?MVVM列表过滤有什么替代方案
.NET 6 WPF 中
ICollectionView 的可用性与多条件过滤实现方案 ICollectionView 从未被弃用,也未在.NET 6中移除,你在System.ComponentModel命名空间下找不到该类型,本质是找错了命名空间:
- 该类型是WPF框架专属类型,并不包含在跨平台的基础类库中,.NET Core/.NET 5+版本下,它和配套的
CollectionViewSource都归属在System.Windows.Data命名空间下,属于WPF项目默认引用的PresentationFramework核心程序集。只要你创建的是标准WPF项目(而非未引用WPF SDK的控制台、类库项目),添加using System.Windows.Data;即可正常使用,不存在兼容问题。 - 大量旧教程标注它在
System.ComponentModel命名空间,是.NET Framework时代的类型转发遗留问题:和集合视图相关的部分辅助接口确实定义在System.ComponentModel下,但ICollectionView核心类型始终属于WPF专属UI组件,因此跨平台API文档中不会标注它对.NET 5/.NET 6的支持信息,不代表它被移除。
MVVM模式下基于ICollectionView实现多条件过滤的标准写法
不需要在视图层编写逻辑,所有过滤逻辑都可以放在ViewModel层实现,完全符合MVVM规范:
注意不要每次过滤都重新生成集合,直接复用
ICollectionView的过滤能力即可获得更好的大列表性能,且原生支持UI虚拟化。
首先在ViewModel中定义原始集合、过滤后的集合视图,以及对应的筛选条件属性:
// 原始数据源,所有增删操作直接操作该集合即可 public ObservableCollection<YourDomainModel> RawItems { get; } = new(); private ICollectionView _filteredItems; // 视图层ListView直接绑定该属性 public ICollectionView FilteredItems { get => _filteredItems; set { _filteredItems = value; OnPropertyChanged(); } } // 筛选条件:对应文本框输入 private string _searchKeyword; public string SearchKeyword { get => _searchKeyword; set { _searchKeyword = value; OnPropertyChanged(); // 条件变化时触发重新过滤 FilteredItems.Refresh(); } } // 筛选条件:对应复选框选中状态 private bool _onlyShowEnabled; public bool OnlyShowEnabled { get => _onlyShowEnabled; set { _onlyShowEnabled = value; OnPropertyChanged(); FilteredItems.Refresh(); } }
在ViewModel构造函数中初始化集合视图,编写统一的过滤判断逻辑:
public YourViewModel() { // 基于原始集合获取默认的集合视图 FilteredItems = CollectionViewSource.GetDefaultView(RawItems); // 编写多条件过滤规则 FilteredItems.Filter = itemObj => { if (itemObj is not YourDomainModel item) return false; // 文本框模糊匹配规则,可根据需要扩展多个字段匹配 bool keywordMatch = string.IsNullOrWhiteSpace(SearchKeyword) || item.Name.Contains(SearchKeyword, StringComparison.OrdinalIgnoreCase) || item.Code.Contains(SearchKeyword, StringComparison.OrdinalIgnoreCase); // 复选框状态匹配规则 bool statusMatch = !OnlyShowEnabled || item.IsEnabled; // 所有条件都满足则保留该项 return keywordMatch && statusMatch; }; }
XAML侧绑定不需要额外配置,直接关联对应属性即可:
<!-- 列表控件绑定过滤后的视图 --> <ListView ItemsSource="{Binding FilteredItems}"> <!-- 列表项模板省略 --> </ListView> <!-- 筛选控件绑定对应条件属性,文本框设置输入即时更新 --> <TextBox Text="{Binding SearchKeyword, UpdateSourceTrigger=PropertyChanged}" Margin="4" PlaceholderText="输入关键词搜索"/> <CheckBox IsChecked="{Binding OnlyShowEnabled}" Margin="4" Content="仅显示启用项"/>
可选替代方案
如果需要做跨平台兼容、不想依赖WPF专属类型,也可以自行在ViewModel层维护一个ObservableCollection<T>类型的过滤结果集合,每次筛选条件变化时从原始集合重新拉取符合条件的项赋值给结果集合。但该方案在列表项超过千条时性能明显差于ICollectionView,且会破坏UI虚拟化的连续性,WPF场景下优先使用ICollectionView即可。
目前从.NET Core 3.0到最新的.NET 8版本,ICollectionView的API行为和.NET Framework时代完全一致,旧教程中的排序、分组、过滤逻辑都可以无缝迁移,唯一需要注意的就是使用正确的命名空间引用。
内容的提问来源于stack exchange,提问作者Roy
相关产品推荐
相关产品推荐

