C# Winforms中DataGridView单元格相乘结果不精确问题求助
WinForms DataGridView 计算精度问题解决方法
我开发WinForms应用时,遇到DataGridView中数量×单价计算总价的精度问题——比如单价是3.469,99,乘以1后得到3.470,00,预期结果应该是3.469,99。
原代码
private void dataGridView1_CellValueChanged(object sender, DataGridViewCellEventArgs e) { if (dataGridView1.Rows.Count > 0) { if (e.ColumnIndex == 1) { if (int.TryParse(dataGridView1.Rows[e.RowIndex].Cells[1].Value?.ToString(), out int qty)) { var price = dataGridView1.Rows[e.RowIndex].Cells[2].Value; var total = dataGridView1.Rows[e.RowIndex].Cells[3]; decimal result = qty * (decimal) price; // <--- 问题所在 total.Value = result; } } } }
更新:
问题原因
- 直接强制转换单元格值为
decimal时,未考虑地区格式差异(比如欧洲地区用逗号做小数分隔符、点做千分位),导致解析过程中出现隐式四舍五入。 - 单元格值可能以字符串形式存储,强制转换时无法正确识别千分位分隔符,导致数值被错误解析。
解决方法
1. 正确解析单价数值
使用decimal.TryParse并指定对应地区文化,确保精确解析带千分位的数值:
- 比如针对德国/欧洲格式(千分位用点、小数用逗号),使用
CultureInfo.CreateSpecificCulture("de-DE")。 - 加上
NumberStyles.Currency | NumberStyles.Number支持解析带格式的数值。
2. 确保总价单元格显示格式正确
设置总价列的单元格格式,避免显示时自动四舍五入。
修改后的代码
using System.Globalization; private void dataGridView1_CellValueChanged(object sender, DataGridViewCellEventArgs e) { if (dataGridView1.Rows.Count == 0 || e.ColumnIndex != 1) return; if (int.TryParse(dataGridView1.Rows[e.RowIndex].Cells[1].Value?.ToString(), out int qty)) { var priceText = dataGridView1.Rows[e.RowIndex].Cells[2].Value?.ToString(); var totalCell = dataGridView1.Rows[e.RowIndex].Cells[3]; // 根据你的地区格式调整文化信息 var culture = CultureInfo.CreateSpecificCulture("de-DE"); if (decimal.TryParse(priceText, NumberStyles.Currency | NumberStyles.Number, culture, out decimal price)) { decimal result = qty * price; totalCell.Value = result; // 设置显示格式,保留两位小数,匹配地区分隔符 totalCell.Style.Format = "#,##0.00"; } } }
额外建议
- 提前设置DataGridView列的
ValueType为typeof(decimal),确保单元格存储的是数值类型而非字符串,从根源避免解析问题。 - 若使用绑定数据源(如
DataTable),建议直接在数据源中计算总价列(比如用表达式列),这样精度控制更稳定,也无需在单元格事件中处理。
内容的提问来源于stack exchange,提问作者Ivan
相关产品推荐
相关产品推荐

