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
相关产品推荐
相关产品推荐

