DataGridView单元格值变更事件触发时出现StackOverflow异常
DataGridView单元格相乘触发StackOverflow异常的解决方案
你的代码触发栈溢出的核心原因是CellValueChanged事件的无限循环调用:当你在事件处理逻辑中修改第6列单元格的值时,这个操作会再次触发CellValueChanged事件,事件反复执行自身,最终耗尽栈空间抛出异常。
修复方案一:限定触发计算的列范围
只在修改的是参与计算的第4、5列时执行逻辑,避免修改第6列触发循环:
private void ReturnCartDGV_CellValueChanged(object sender, DataGridViewCellEventArgs e) { // 仅当修改的是第4或第5列时才执行计算 if (e.ColumnIndex != 4 && e.ColumnIndex != 5) return; // 排除无效行(如新增的空白行) if (e.RowIndex < 0 || e.RowIndex >= ReturnCartDGV.Rows.Count - 1) return; long totalPrice; var currentRow = ReturnCartDGV.Rows[e.RowIndex]; // 检查单元格值不为空,防止转换报错 if (currentRow.Cells[4].Value == null || currentRow.Cells[5].Value == null) return; totalPrice = Convert.ToInt64(currentRow.Cells[4].Value) * Convert.ToInt64(currentRow.Cells[5].Value); currentRow.Cells[6].Value = totalPrice.ToString(); }
修复方案二:临时禁用事件再修改值
通过临时解绑事件避免循环触发,修改完成后重新绑定:
private void ReturnCartDGV_CellValueChanged(object sender, DataGridViewCellEventArgs e) { if (e.RowIndex < 0 || e.RowIndex >= ReturnCartDGV.Rows.Count - 1) return; long totalPrice; var currentRow = ReturnCartDGV.Rows[e.RowIndex]; if (currentRow.Cells[4].Value == null || currentRow.Cells[5].Value == null) return; // 临时解绑事件,防止修改值时触发循环 ReturnCartDGV.CellValueChanged -= ReturnCartDGV_CellValueChanged; totalPrice = Convert.ToInt64(currentRow.Cells[4].Value) * Convert.ToInt64(currentRow.Cells[5].Value); currentRow.Cells[6].Value = totalPrice.ToString(); // 重新绑定事件 ReturnCartDGV.CellValueChanged += ReturnCartDGV_CellValueChanged; }
额外注意事项
- 用事件参数
e.RowIndex代替CurrentCell.RowIndex,避免CurrentCell在事件执行过程中发生偏移导致的错误 - 增加单元格值非空判断,避免转换时抛出空引用异常
内容的提问来源于stack exchange,提问作者ZainErto
相关产品推荐
相关产品推荐

