C# DataGridView文件列表过滤优化及异常问题求助
问题分析与解决方案
原代码的核心问题
- 原始数据丢失:每次过滤直接删除
dateienList中的元素,导致无法恢复到完整文件列表,后续搜索无法基于全部数据重新过滤。 - 性能低效:大量删除操作频繁触发
BindingList的变更事件,导致DataGridView多次刷新,1000条数据时卡顿明显。 - 索引异常:删除元素时
DataGridView的行索引与列表不同步,引发ArgumentOutOfRangeException。
你尝试的代码无效原因
- 第一个方案:
dateienList = neueDateienListe;仅修改了变量引用,DataGridView绑定的是原BindingList实例,无法感知新列表的存在,因此无过滤效果。 - 第二个方案:最后一行
neueDateienListe = dateienList;将新创建的过滤列表覆盖为原列表,等于白执行了过滤逻辑。
推荐解决方案:基于原始数据+BindingSource过滤(高效且无异常)
使用BindingSource作为DataGridView的中间数据源,它支持直接过滤,能避免频繁刷新的性能问题,同时保留原始数据用于重复过滤。
步骤1:定义全局变量
在窗体类中保留原始完整数据与绑定源:
// 存储所有选中的文件,永远不修改这个列表 private List<Datei> _originalDateienList = new List<Datei>(); private BindingSource _bindingSource = new BindingSource();
步骤2:初始化数据源
在加载窗体或选中文件后,初始化绑定源:
// 假设这里是你加载选中文件的逻辑,将所有文件存入_originalDateienList // _originalDateienList = 获取选中文件的列表; // 将绑定源设置为DataGridView的数据源 dataGridView1.DataSource = _bindingSource; // 初始时显示全部数据 _bindingSource.DataSource = _originalDateienList;
步骤3:优化搜索按钮逻辑
private void durchsuchenButton(object sender, EventArgs e) { string searchingText = textBox1.Text.Trim().ToLower(); if (string.IsNullOrEmpty(searchingText)) { // 搜索为空时,恢复显示全部数据 _bindingSource.DataSource = _originalDateienList; } else { // 基于原始数据过滤,避免修改原始列表 var filteredList = _originalDateienList.Where(datei => datei.dateiname.ToLower().Contains(searchingText)).ToList(); _bindingSource.DataSource = filteredList; } // 强制刷新一次即可 dataGridView1.Refresh(); }
备选方案:手动更新BindingList(不使用BindingSource)
如果坚持使用BindingList,需要避免直接替换引用,而是清空原列表后添加过滤结果:
// 全局的BindingList,绑定到DataGridView private BindingList<Datei> _dateienList = new BindingList<Datei>(); // 原始完整数据 private List<Datei> _originalDateienList = new List<Datei>(); // 搜索按钮逻辑 private void durchsuchenButton(object sender, EventArgs e) { string searchingText = textBox1.Text.Trim().ToLower(); // 先清空当前绑定列表 _dateienList.Clear(); if (string.IsNullOrEmpty(searchingText)) { // 添加全部原始数据 foreach (var datei in _originalDateienList) { _dateienList.Add(datei); } } else { // 添加过滤后的数据 foreach (var datei in _originalDateienList.Where(d => d.dateiname.ToLower().Contains(searchingText))) { _dateienList.Add(datei); } } // 通知DataGridView数据变更 _dateienList.ResetBindings(); }
关键优化点
- 保留原始数据:所有过滤操作基于原始完整列表,避免数据丢失,支持重复搜索。
- 一次性更新数据源:不管是替换
BindingSource的数据源,还是清空后批量添加元素,都只触发一次数据变更事件,大幅提升大量数据时的过滤速度。 - 避免索引异常:不再直接删除列表元素,而是重新生成或批量添加,确保
DataGridView的行索引与列表同步。
内容的提问来源于stack exchange,提问作者LFLJM
相关产品推荐
相关产品推荐

