You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

优化向DataGridView批量添加数据的代码:AddRange使用疑问求解

针对DataGridView批量加万级行的性能优化方案

第一优先级优化:先抑制UI重绘开销

逐行加行慢的核心原因,是每调用一次Rows->Add()就会触发一次控件重绘、布局计算、事件通知的全流程,25000次循环等于产生了25000次无意义的UI渲染开销,这部分可以通过控件自带的批量更新开关直接砍掉:

// 批量操作前关闭重绘锁定
dgv->BeginUpdate();
try
{
    // 所有加行、赋值的逻辑全部写在这个块内
}
finally
{
    // 操作完成后恢复重绘,一次性渲染所有内容
    dgv->EndUpdate();
}

关于AddRange方法的正确用法

你之前对AddRange的认知存在几个常见误区,按步骤修正就能正常使用:

  • 不需要手动对齐列:只要你的IDColumn、ModColumn、RunColumn已经提前添加到dgv->Columns集合里,后续新建的DataGridViewRow实例不需要手动同步列配置,直接按列索引给单元格赋值即可,不会出现列不匹配的问题
  • 不需要等AddRange调用后再填数据:完全可以先把所有行对象的单元格值全部填充完成,再一次性传给AddRange,比先Add再赋值的效率高很多
  • 新建行实例的语法修正:C++/CLI下DataGridViewRow是托管引用类型,不能像值类型那样直接声明,必须用gcnew创建实例,你之前写的DataGridViewRow Test;是无法正常工作的

对应修正后的示例代码:

// 已知总行数等于m_Items->Length,提前初始化对应长度的行集合数组
array<DataGridViewRow^>^ batchRows = gcnew array<DataGridViewRow^>(m_Items->Length);

for (int i = 0; i < m_Items->Length; i++)
{
    // 逐次创建独立的托管行实例
    batchRows[i] = gcnew DataGridViewRow();
    // 直接给对应单元格赋值,和你原来的赋值逻辑完全一致
    batchRows[i]->Cells[this->IDColumn->Index]->Value = safe_cast<System::Object^>(0);
    batchRows[i]->Cells[this->ModColumn->Index]->Value = /* 替换为你原逻辑里的数据库取数 */;
    batchRows[i]->Cells[this->RunColumn->Index]->Value = /* 替换为你原逻辑里的数据库取数 */;
}

// 一次性把所有填充好的行批量添加到dgv中
dgv->Rows->AddRange(batchRows);

更高性能的可选优化(适配万级以上行规模)

如果你的行规模达到2.5万甚至更高,手动操作行集合的方式依然会占用较多UI线程资源,可以改用数据绑定模式彻底绕开逐行操作的开销:

  • 提前关闭dgv的自动生成列:设置dgv->AutoGenerateColumns = false,把已有的3个列的DataPropertyName属性绑定到对应数据实体的字段名上
  • 准备一个和数据字段一一对应的简单托管实体类
  • 把所有从数据库取出的数据实例放到BindingList<T>集合中,最后直接给dgv->DataSource赋值这个集合

这个模式下,dgv只会在绑定数据源时触发一次全量渲染,整体耗时会比手动AddRange的方式再缩短70%以上,同时内存占用也会更低。


内容的提问来源于stack exchange,提问作者NeonGlow

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.24 03:15:03