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

ASP.NET C#添加GridViewRow实现小计的报错与累加问题修复

解决GridView添加小计行报错及累加错误的问题

一、解决添加小计行报错的问题

你遇到的gvData.Rows.Add(row);执行失败,核心原因是在OnRowCreated事件中直接操作GridView的Rows集合时机不对——这个事件是GridView逐行构建的过程中触发的,此时Rows集合处于动态构建状态,直接添加行会干扰控件内部的渲染逻辑,引发状态冲突。

我们可以修改AddTotalRow方法,改为直接操作GridView内部的Table控件,通过指定索引插入行,避开Rows集合的状态限制:

private void AddTotalRow(int insertIndex, string labelText, string value, string completed)
{
    GridViewRow row = new GridViewRow(insertIndex, 0, DataControlRowType.DataRow, DataControlRowState.Normal);
    row.BackColor = ColorTranslator.FromHtml("#F9F9F9");
    row.Cells.AddRange(new TableCell[4] { 
        new TableCell(), 
        new TableCell{ Text = labelText, HorizontalAlign = HorizontalAlign.Right }, 
        HyperLinkCell(value, "http://www.yahoo.com"), 
        HyperLinkCell(completed, "http://www.google.com")
    });
    // 获取GridView内部的Table容器,插入到指定位置
    Table table = gvData.Controls[0] as Table;
    table.Rows.AddAt(insertIndex, row);
}

然后在OnRowCreated中调用时,传入要插入的索引(当前行的索引,这样小计行就会出现在当前年份数据的上方):

this.AddTotalRow(e.Row.RowIndex, "Sub Total", subTotal.ToString("C2"), subTotalCompleted.ToString("C2"));

二、解决小计累加错误的问题

第二个小计的Completed列累加了第一个小计的值,是因为subTotal和subTotalCompleted这两个累加变量在完成一次小计计算后没有重置为0,导致下一次累加时会带上之前的小计结果。

修改OnRowCreated中的逻辑,在添加完小计行后立即重置这两个变量:

if (year != currentYear)
{
    if (e.Row.RowIndex > 0)
    {
        for (int i = subTotalRowIndex; i < e.Row.RowIndex; i++)
        {
            // 注意:如果单元格文本带货币符号,建议用decimal.Parse解析更稳妥
            subTotal += int.Parse(gvData.Rows[i].Cells[2].Text.Replace("$", "").Replace(",", ""));
            subTotalCompleted += int.Parse(gvData.Rows[i].Cells[3].Text.Replace("$", "").Replace(",", ""));
        }
        this.AddTotalRow(e.Row.RowIndex, "Sub Total", subTotal.ToString("C2"), subTotalCompleted.ToString("C2"));
        // 重置累加变量,避免下一次计算重复累加
        subTotal = 0;
        subTotalCompleted = 0;
        subTotalRowIndex = e.Row.RowIndex;
    }
    currentYear = year;
}

另外,在OnDataBound事件中完成最后一次小计后,也记得重置变量:

protected void OnDataBound(object sender, EventArgs e)
{
    if(subTotalRowIndex < gvData.Rows.Count)
    {
        for (int i = subTotalRowIndex; i < gvData.Rows.Count; i++)
        {
            subTotal += int.Parse(gvData.Rows[i].Cells[2].Text.Replace("$", "").Replace(",", ""));
            subTotalCompleted += int.Parse(gvData.Rows[i].Cells[3].Text.Replace("$", "").Replace(",", ""));
        }
        Table table = gvData.Controls[0] as Table;
        this.AddTotalRow(table.Rows.Count, "Sub Total", subTotal.ToString("C2"), subTotalCompleted.ToString("C2"));
        // 重置变量
        subTotal = 0;
        subTotalCompleted = 0;
    }
}

额外优化建议

如果单元格文本是带货币格式的(比如$1,234.00),直接用int.Parse会报错,建议改用decimal.Parse并指定格式解析:

subTotalCompleted += (int)decimal.Parse(gvData.Rows[i].Cells[3].Text, System.Globalization.NumberStyles.Currency);

这样可以兼容各种货币格式的文本转换,避免出现转换异常。


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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.27 07:00:51