DataGridView可见行第6列求和时遇输入字符串格式异常问题
解决DataGridView可见行求和时的格式转换异常
你遇到的"Input string was not in a correct format"异常,核心问题是你试图把无法转换为整数的字符串强转成int类型,咱们一步步分析原因并修复:
常见触发原因
- 单元格值为空或无效:当单元格没有数据时,
Value可能是null或者DBNull.Value,直接调用ToString()会得到空字符串或者"System.DBNull",这两种都无法被Convert.ToInt32解析。 - 单元格内容不是纯整数:如果单元格里是小数、带货币符号(比如¥100)、或者包含非数字字符,强转肯定会报错。
- 列索引可能搞错了:DataGridView的列索引是从0开始计数的,你说的"第6列"对应的索引应该是
5而非6——如果索引错了,取到的单元格内容完全不符合预期,自然会转换失败。
修复后的完整代码
我把你的事件处理代码做了优化,重点修复了求和部分的转换逻辑,同时简化了冗余代码:
private void toolStripMenuItem2_Click(object sender, EventArgs e) { // 隐藏选中行的逻辑保留,优化BindingContext的使用 CurrencyManager currencyManager1 = (CurrencyManager)BindingContext[addSellItemsDgv.DataSource]; currencyManager1.SuspendBinding(); foreach (DataGridViewRow row in addSellItemsDgv.SelectedRows) { addSellItemsDgv.CurrentCell = null; row.Visible = false; } currencyManager1.ResumeBinding(); // 记得恢复绑定,避免后续数据更新异常 addSellItemsDgv.Refresh(); int count = 0; // 遍历可见行求和 foreach (DataGridViewRow row in addSellItemsDgv.Rows) { if (row.Visible && !row.IsNewRow) { // 排除底部的空白新增行 DataGridViewCell cell = row.Cells[6]; // 这里务必确认索引:第6列实际索引应为5? if (cell.Value != null && cell.Value != DBNull.Value) { string cellText = cell.Value.ToString().Trim(); if (int.TryParse(cellText, out int cellValue)) { count += cellValue; } // 可选:转换失败时可添加日志或提示 // else { MessageBox.Show($"行{row.Index}的单元格内容不是有效整数"); } } } } addSellTtlCostLbl.Text = count.ToString(); }
关键优化点说明
- 安全转换逻辑:用
int.TryParse替代Convert.ToInt32,它不会抛出异常,还能通过返回值判断转换是否成功,避免程序崩溃。 - 空值判断:先检查单元格
Value是否为null或DBNull.Value,避免调用ToString()时出现空引用异常。 - 冗余代码消除:遍历
Rows时直接用当前row对象获取单元格,不需要再通过row.Index重复取Rows[row.Index]。 - 新增行排除:加上
!row.IsNewRow判断,避免把DataGridView底部的空白新增行算进去。 - 恢复数据绑定:原来的代码只调用了
SuspendBinding(),补上ResumeBinding()保证后续数据绑定正常工作。
额外建议
如果你的第6列存储的是金额(带小数的数值),建议用decimal.TryParse来转换,避免精度丢失:
decimal total = 0; // ... if (decimal.TryParse(cellText, out decimal cellValue)) { total += cellValue; } addSellTtlCostLbl.Text = total.ToString("C"); // 可以格式化显示为货币格式
内容的提问来源于stack exchange,提问作者Huda
相关产品推荐
相关产品推荐

