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

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.13 10:30:54