DataGridView中Try-Catch未捕获异常?删除最后一行时出错
问题场景
在DataGridView中删除行,当所有行被删除后弹出异常,但已在SelectionChanged事件中使用Try-Catch块却未捕获到该异常。
相关代码
Private Sub materialsGridView_SelectionChanged(sender As Object, e As EventArgs) Handles materialsGridView.SelectionChanged Try materialSelectedindex = materialsGridView.CurrentRow.Index Catch ex As Exception materialSelectedindex = -1 End Try End Sub Private Sub delRowBtn_Click(sender As Object, e As EventArgs) Handles delRowBtn.Click If (materialSelectedindex = -1) Then MsgBox("Please select a row") Return End If materialsGridView.Rows.RemoveAt(materialSelectedindex) End Sub
错误截图

异常未被捕获的核心原因
你的Try-Catch仅作用于SelectionChanged事件内获取CurrentRow.Index的操作,但实际抛出的异常可能来自以下未被覆盖的代码路径:
删除操作本身触发的内部异常
当删除最后一行时,materialsGridView.Rows.RemoveAt(materialSelectedindex)可能触发DataGridView的内部逻辑异常(比如数据绑定同步问题、UI渲染冲突等),这些异常发生在delRowBtn_Click方法中,而该方法没有对应的异常处理块。SelectionChanged事件的覆盖范围有限
即使SelectionChanged中的Try-Catch能捕获获取索引的异常,但删除最后一行后,DataGridView的其他内部事件(如RowStateChanged、CellStateChanged)或关联逻辑可能尝试访问CurrentRow,这些场景不在你的Try-Catch覆盖范围内,仍会抛出未被捕获的异常。Try-Catch的低效性与遗漏场景
你通过捕获异常来处理CurrentRow为null的情况,但这种方式不仅效率低,还可能遗漏其他潜在异常触发点。直接通过null判断可以从根源避免异常发生,而非事后捕获。
优化方案
1. 提前判断行状态,避免无效操作
修改删除按钮的点击事件,先判断是否有可删除的行,以及选中索引是否有效:
Private Sub delRowBtn_Click(sender As Object, e As EventArgs) Handles delRowBtn.Click ' 先判断是否存在行 If materialsGridView.Rows.Count = 0 Then MsgBox("没有可删除的行") Return End If ' 判断选中索引是否有效 If materialSelectedindex = -1 OrElse materialSelectedindex >= materialsGridView.Rows.Count Then MsgBox("请选择有效的行") Return End If ' 执行删除操作 materialsGridView.Rows.RemoveAt(materialSelectedindex) ' 删除后重置选中索引 materialSelectedindex = -1 End Sub
2. 替换Try-Catch为null判断,从根源避免异常
修改SelectionChanged事件,直接判断CurrentRow是否为null,无需依赖异常捕获:
Private Sub materialsGridView_SelectionChanged(sender As Object, e As EventArgs) Handles materialsGridView.SelectionChanged ' 用null判断替代Try-Catch,更高效且避免异常 materialSelectedindex = If(materialsGridView.CurrentRow IsNot Nothing, materialsGridView.CurrentRow.Index, -1) End Sub
内容的提问来源于stack exchange,提问作者ronie arnibal

