WPF添加自定义过滤后DataGrid绑定异常,新增行无法显示
问题分析
你的核心问题在于:当通过新建TempCollection生成过滤结果并赋值给FilteredCollection后,这个新集合和原始的csGlobal.LogList没有关联。原始集合新增行时,TempCollection不会自动同步这些新增项,导致DataGrid无法显示新内容;而勾选复选框时会重新执行ApplyFilter,重新生成过滤集合,所以能正常展示过滤后的数据。
解决方案
推荐使用WPF原生的ICollectionView实现过滤,这是最贴合WPF绑定机制的方式,无需手动维护过滤集合:
方法一:使用ICollectionView(推荐)
- 在ViewModel中声明
ICollectionView类型属性,替代原FilteredCollection:
private ICollectionView _logCollectionView; public ICollectionView LogCollectionView { get { if (_logCollectionView == null) { // 基于原始集合创建视图 _logCollectionView = CollectionViewSource.GetDefaultView(csGlobal.LogList); // 设置过滤规则 _logCollectionView.Filter = item => { var logItem = item as cs_Log; if (logItem == null) return false; return ((logItem.sType == "Information" && InfoInclude) || (logItem.sType == "Warning" && WarnInclude) || (logItem.sType == "Error" && ErrInclude)); }; } return _logCollectionView; } }
- 修改XAML中DataGrid的绑定目标:
<DataGrid ItemsSource="{Binding LogCollectionView}" ... />
- 修改复选框属性的setter,仅刷新视图过滤而非重建集合:
public bool InfoInclude { get { return _infoinclude; } set { _infoinclude = value; OnPropertyChanged("InfoInclude"); // 刷新过滤逻辑 LogCollectionView.Refresh(); } } // WarnInclude和ErrInclude的setter做同样修改
- 移除原
FilteredCollection属性与ApplyFilter方法,ICollectionView会自动同步原始集合的新增/删除操作,并自动应用过滤规则。
方法二:手动监听原始集合变更(特殊场景适用)
若坚持使用自定义FilteredCollection,需监听原始集合的CollectionChanged事件,同步新增项:
- 在ViewModel初始化时添加事件监听:
public YourViewModel() { csGlobal.LogList.CollectionChanged += LogList_CollectionChanged; } private void LogList_CollectionChanged(object sender, NotifyCollectionChangedEventArgs e) { if (e.Action == NotifyCollectionChangedAction.Add) { // 遍历新增项,判断是否符合过滤条件 foreach (cs_Log newItem in e.NewItems) { if (((newItem.sType == "Information" && InfoInclude) || (newItem.sType == "Warning" && WarnInclude) || (newItem.sType == "Error" && ErrInclude))) { FilteredCollection.Add(newItem); } } } // 如需处理删除、替换等操作,可在此补充对应逻辑 }
- 修改
ApplyFilter方法为清空现有集合再添加符合条件项,而非新建集合:
void ApplyFilter() { FilteredCollection.Clear(); foreach (cs_Log item in csGlobal.LogList) { if (((item.sType == "Information" && InfoInclude) || (item.sType == "Warning" && WarnInclude) || (item.sType == "Error" && ErrInclude))) { FilteredCollection.Add(item); } } }
- 确保
FilteredCollection初始化时为非空集合:
private ObservableCollection<cs_Log> _filteredcollection = new ObservableCollection<cs_Log>(); public ObservableCollection<cs_Log> FilteredCollection { get { return _filteredcollection; } set { _filteredcollection = value; OnPropertyChanged("FilteredCollection"); // 移除手动设置ItemsSource的代码,改用XAML绑定 } }
关键说明
ICollectionView是WPF专为集合过滤、排序、分组设计的组件,直接关联原始集合,任何变更都会自动同步到视图,是最优雅的解决方案。- 手动监听的方式需要维护多端同步逻辑,容易出现遗漏(比如原始集合删除项未同步),仅适合特殊场景使用。
内容的提问来源于stack exchange,提问作者MKamal
相关产品推荐
相关产品推荐

