遍历DataGridView收集值对时出现配对错误,求解决思路
DataGridView中Point Codes与Offset配对错误的解决思路
你的核心问题出在循环逻辑错误,导致每一行的数据被拆分成多个对象存入列表,而非将同一行的Point Codes和Offset配对到同一个对象中。结合你的代码和表格结构,具体问题点及修复方案如下:
问题分析
- 嵌套循环导致对象重复创建:遍历每一行后又遍历每一列,且每次列循环都新建
PontCodeAndOffsets对象,最终每一行会生成3个对象(对应3列),其中仅1个对象有PointCode、1个有Offset,剩下1个为空,完全不符合“配对存入”的需求。 - 硬编码单元格索引风险:直接使用
row.Cells[1]、row.Cells[2]依赖列的固定顺序,若表格列顺序调整,会直接导致取值错误。 - 类型转换不安全:Offset列是String类型,直接强制转换
(double)row.Cells[2].Value,若单元格值无法转换为double会抛出异常。 - 未排除空行:DataGridView默认最后一行是可编辑的空行(
IsNewRow为true),会被误加入列表。
修复方案
1. 修正循环逻辑
移除列的遍历循环,每一行仅创建一个PontCodeAndOffsets对象,一次性完成PointCode和Offset的赋值后再加入列表。
2. 优化取值方式
通过列名获取单元格,避免索引硬编码,提升代码健壮性。
3. 安全处理类型转换
使用double.TryParse将String类型的Offset转换为double,避免转换失败报错。
4. 排除空行
判断row.IsNewRow,跳过DataGridView的默认空行。
修正后的代码
// 从DataGridView提取Point Codes和Offset,配对后存入列表 public List<PontCodeAndOffsets> DataGridViewtoListByCorridor(string corridorname) { List<PontCodeAndOffsets> ListPCandO = new List<PontCodeAndOffsets>(); foreach (DataGridView dgv in this.Controls.OfType<DataGridView>()) { if (dgv.Name == corridorname) { // 通过列名获取索引,避免硬编码 int pointCodeColIndex = dgv.Columns["Point Codes"].Index; int offsetColIndex = dgv.Columns["Offsets"].Index; foreach (DataGridViewRow row in dgv.Rows) { // 跳过DataGridView默认的空行 if (row.IsNewRow) continue; // 获取单元格值并判断非空 var pointCodeValue = row.Cells[pointCodeColIndex].Value; var offsetValue = row.Cells[offsetColIndex].Value; if (pointCodeValue != null && offsetValue != null) { PontCodeAndOffsets PCandOffsets = new PontCodeAndOffsets(); PCandOffsets.PointCode = pointCodeValue.ToString(); // 安全转换Offset为double类型 if (double.TryParse(offsetValue.ToString(), out double offset)) { PCandOffsets.Offset = offset; ListPCandO.Add(PCandOffsets); } } } } } return ListPCandO; }
额外验证建议
- 调试时可在添加对象到列表前,打印
PCandOffsets的属性值,确认PointCode和Offset是否正确配对。 - 若表格列名可能变动,可考虑用列的
DisplayName或其他固定标识获取列索引,进一步提升代码灵活性。
内容的提问来源于stack exchange,提问作者Walltumbler
相关产品推荐
相关产品推荐

