定时器切换DataGridView行时出现ArgumentOutOfRangeException的解决方法
修复DataGridView索引越界异常的方案
首先,咱们来拆解你遇到的ArgumentOutOfRangeException问题:这个异常说明你最后一行代码里的lastRowIndex超出了links_dgv.Rows的有效索引范围(有效索引是从0到Rows.Count - 1)。核心原因有这几个:
- 当循环没找到符合条件的行时(比如剩余行的
Cells[0]全为null,或者lastRowIndex已经是倒数第二行),lastRowIndex会保持原值,如果这个值本身无效(比如初始为-1,或者等于Rows.Count),就会触发报错。 - 你的循环范围写窄了:
i < links_dgv.Rows.Count - 1会导致最后一行永远不会被遍历到,因为最大的i只能到Rows.Count - 2。 - 没处理
DataGridView为空(无数据行)的边界情况。
下面是修复后的完整代码,我会逐个解释关键调整点:
// 先处理边界情况:如果没有有效数据行,直接返回 if (links_dgv.Rows.Count == 0 || (links_dgv.AllowUserToAddRows && links_dgv.Rows.Count == 1)) { Console.WriteLine("没有可选中的行"); return; } // 计算最大有效行索引:如果允许用户添加新行,要排除最后一行空行 int maxRowIndex = links_dgv.Rows.Count - (links_dgv.AllowUserToAddRows ? 1 : 0); int targetRowIndex = -1; // 从lastRowIndex的下一行开始遍历所有有效行 for (int i = lastRowIndex + 1; i <= maxRowIndex; i++) { // 同时验证行对象和单元格不为null if (links_dgv.Rows[i] != null && links_dgv.Rows[i].Cells[0] != null) { targetRowIndex = i; break; } } // 找到有效行的情况 if (targetRowIndex != -1) { lastRowIndex = targetRowIndex; Console.WriteLine(lastRowIndex.ToString()); DataGridViewCell cell = links_dgv.Rows[lastRowIndex].Cells[0]; // 这里可以补充选中行的逻辑: // links_dgv.ClearSelection(); // links_dgv.Rows[lastRowIndex].Selected = true; } else { // 遍历完当前位置后无有效行,回到第一行寻找 Console.WriteLine("已遍历完所有有效行,回到第一行"); for (int i = 0; i <= maxRowIndex; i++) { if (links_dgv.Rows[i] != null && links_dgv.Rows[i].Cells[0] != null) { lastRowIndex = i; Console.WriteLine(lastRowIndex.ToString()); DataGridViewCell cell = links_dgv.Rows[lastRowIndex].Cells[0]; // 补充选中逻辑 break; } } }
关键修复细节:
- 边界前置检查:先判断
DataGridView是否有有效数据行,直接避免空集合访问的问题。 - 动态计算有效行范围:用
maxRowIndex适配AllowUserToAddRows的设置,自动排除最后一行的空行。 - 双重有效性验证:同时检查行对象和单元格不为
null,避免行本身无效的情况。 - 无结果兜底处理:当当前位置之后没有有效行时,添加了回到第一行的逻辑,确保
lastRowIndex始终是有效值。
另外,记得给lastRowIndex设置合理的初始值(比如初始化为-1,或者第一行的索引0),这样第一次循环能正常启动。
内容的提问来源于stack exchange,提问作者Onur Can
相关产品推荐
相关产品推荐

