C# WinForms DataGridView未将对象引用设置到对象实例错误如何排查
异常根因分析
从抛出的堆栈可以明确,空引用异常发生在DataGridViewButtonCell的私有绘制方法执行阶段,属于UI控件绘制逻辑异常,和你的业务功能代码无关,所以会出现业务功能正常执行但控件表面出现红叉的现象。
常见触发场景:
- 跨线程修改了DataGridView的数据源、单元格属性,UI线程执行绘制时拿到了未初始化完成的半更新状态数据
- 按钮列的单元格值、样式属性、显示文本存在null值,控件原生绘制逻辑没有兼容空值场景
- 行切换时你修改了对应行按钮的状态(如启用/禁用、修改文本),修改操作未同步到UI线程,或修改后未通知控件刷新,导致绘制时读取到无效对象
排查步骤
- 检查所有修改DataGridView数据源、单元格内容、按钮列属性的代码,确认是否存在非UI线程执行UI修改的操作
- 给DataGridView的
CellPainting事件添加断点,在行切换触发重绘时,检查当前行按钮单元格的Value、Style、Text属性是否为null - 检查绑定给按钮列的数据源字段是否存在空值,确认按钮列是否配置了空值默认显示规则
修复方案
- 所有修改DataGridView相关UI属性的操作,必须封送到UI线程执行,参考代码:
if (dataGridView1.InvokeRequired) { dataGridView1.Invoke(new Action(() => { // 此处写修改数据源、单元格属性的逻辑 dataGridView1.Rows[e.RowIndex].Cells["OperateBtn"].Value = "编辑"; })); } else { // 已在UI线程可直接修改 dataGridView1.Rows[e.RowIndex].Cells["OperateBtn"].Value = "编辑"; }
- 初始化按钮列时配置空值兼容规则,避免值为空导致绘制异常:
DataGridViewButtonColumn operateCol = new DataGridViewButtonColumn(); operateCol.Name = "OperateCol"; // 若所有行按钮文本统一,直接开启列文本复用,无需行级赋值 operateCol.Text = "操作"; operateCol.UseColumnTextForButtonValue = true; // 若需每行自定义按钮文本,配置空值默认兜底 operateCol.DefaultCellStyle.NullValue = "查看";
- 可通过捕获DataGridView的
DataError事件避免绘制异常透出导致红叉:
private void dataGridView1_DataError(object sender, DataGridViewDataErrorEventArgs e) { // 可在此处添加异常日志 e.ThrowException = false; e.Cancel = true; }
- 行切换修改按钮状态后,主动调用对应单元格的
Invalidate方法强制刷新,确保绘制时读取到最新状态。
内容的提问来源于stack exchange,提问作者KorBee
相关产品推荐
相关产品推荐

