ArgumentOutOfRangeException on Datagridview with 1 row



我有一个奇怪的问题。我有一个表单,上面有 2 个无限的数据网格视图和 2 个按钮。使用按钮,我将行从 1 个数据网格切换到另一个数据网格。 一开始,左侧数据网格填充了许多行,右侧数据网格为空。因此,当我单击"添加"按钮时,左侧数据网格中的选定行将被删除并添加到右侧数据网格中。使用"删除"按钮,右侧数据网格的选定行将添加回左侧数据网格。

当右侧数据网格中只有一行,并且我选择它以"删除"它时,该行将从右侧数据网格中删除并添加到左侧,无一例外。现在我遇到一种情况,左侧数据网格中只有一行,当我单击"添加"将其移动到右侧数据网格时,我得到一个 ArgumentOutOfRangeException(索引超出范围......

下面是引发异常的代码

For i As Integer = DgvLeft.SelectedRows.Count - 1 To 0 Step -1
ind = DgvLeft.SelectedRows(i).Index
If ind > 0 Then
DgvLeft.Rows.RemoveAt(ind)
Else
DgvLeft.Rows.Remove(DgvLeft.SelectedRows(i))
End If
Next

所以我将行索引存储在一个变量中。我第一次使用 RemoveAt 函数时,抛出了异常。为了解决这个问题,我添加了 If 结构并尝试了 Remove 函数。但再次抛出异常。

我不明白为什么会抛出异常。我对"删除"按钮使用相同的代码,但它没有发生。此外,当我将 RowIndex 存储在变量中时,索引是已知的,但当我尝试删除行时则不是。

有人可以帮助我解决这个奇怪的问题吗?

由于发布的for循环已"断开",因此我觉得没有必要质疑您在这里要完成的任务。但是,鉴于您描述的内容,表单上有两个网格和两个按钮(添加/删除(。单击"添加"按钮时,它将"所选行"从"左"网格移动到"右"网格,然后从"左"网格中删除"所选行"。如果单击"删除"按钮,则会发生相反的过程,将"所选行"从右侧网格移动到左侧网格,然后从右侧网格中删除所选行。

如果这是正确的,那么看起来你正在使它变得比它必须的更复杂。如果您使用某种形式的数据源,这将容易得多。但是,为了分解上述问题,似乎有两种方法可能会派上用场。第一个可以简单地将所选行从一个给定网格添加到另一个给定网格。下一个方法将简单地从给定网格中删除选定的行。实现这两种方法后,"添加"按钮将是...

AddSelectedRows(dgvLeft, dgvRight)
RemoveSelectedRows(dgvLeft)

删除按钮将是...

AddSelectedRows(dgvRight, dgvLeft)
RemoveSelectedRows(dgvRight)

在我解释下面的代码之前,应该注意的是,您当前发布的代码正在使一个巨大的编程"禁忌",毫无疑问对您来说是一个问题。正如 Mary 和其他人所指出的那样,"在循环中更改计数器变量的值或(如代码所做的那样(更改它正在循环的集合很少(如果有的话(。

尝试下面的代码可能会使事情变得更容易,

Private Sub Form1_Load(sender As Object, e As EventArgs) Handles MyBase.Load
AddColumns(dgvLeft)
AddColumns(dgvRight)
FillGrid(dgvLeft)
End Sub
Private Sub FillGrid(dgv As DataGridView)
For i = 0 To 15
dgv.Rows.Add("C0R" + i.ToString(), "C1R" + i.ToString(), "C2R" + i.ToString())
Next
End Sub
Private Sub AddColumns(dgv As DataGridView)
Dim txtCol = New DataGridViewTextBoxColumn()
txtCol.Name = "Col0"
txtCol.HeaderText = "Col 0"
dgv.Columns.Add(txtCol)
txtCol = New DataGridViewTextBoxColumn()
txtCol.Name = "Col1"
txtCol.HeaderText = "Col 1"
dgv.Columns.Add(txtCol)
txtCol = New DataGridViewTextBoxColumn()
txtCol.Name = "Col2"
txtCol.HeaderText = "Col 2"
dgv.Columns.Add(txtCol)
End Sub
Private Sub btnAdd_Click(sender As Object, e As EventArgs) Handles btnAdd.Click
AddSelectedRows(dgvLeft, dgvRight)
RemoveSelectedRows(dgvLeft)
End Sub

Private Sub btnDelete_Click(sender As Object, e As EventArgs) Handles btnDelete.Click
AddSelectedRows(dgvRight, dgvLeft)
RemoveSelectedRows(dgvRight)
End Sub
Private Sub RemoveSelectedRows(dgv As DataGridView)
Dim totalRowsToDelete = dgv.SelectedRows.Count
Dim selectedRow As DataGridViewRow
For i = totalRowsToDelete - 1 To 0 Step -1
selectedRow = dgv.SelectedRows(i)
If (Not selectedRow.IsNewRow) Then
dgv.Rows.RemoveAt(dgv.SelectedRows(i).Index)
End If
Next
End Sub
Private Sub AddSelectedRows(sourceDGV As DataGridView, destinationDGV As DataGridView)
Dim selectedRowCount = sourceDGV.Rows.GetRowCount(DataGridViewElementStates.Selected)
If (selectedRowCount > 0) Then
Dim selectedRow As DataGridViewRow
For i = 0 To selectedRowCount - 1
selectedRow = sourceDGV.SelectedRows(i)
If (Not selectedRow.IsNewRow) Then
destinationDGV.Rows.Add(selectedRow.Cells(0).Value.ToString(),
selectedRow.Cells(1).Value.ToString(),
selectedRow.Cells(2).Value.ToString())
End If
Next
End If
End Sub

您正在更改 For 循环中DgvLeft.SelectedRows.Count的值。 尝试。。。

Dim RowCount As Integer = DgvLeft.SelectedRows.Count
For i As Integer = RowCount - 1 To 0 Step -1

我要感谢 Mary 的回答,因为这让我思考了我的代码。 我查看了"删除"按钮的代码,其中我使用相同的 for 循环,并且该代码不会引发异常。所以我的两个按钮的代码之间一定有区别。

这是我在"添加"按钮中的一段扩展代码:

For i As Integer = DgvLeft.SelectedRows.Count - 1 To 0 Step -1
'fill the array with the row values
For j As Integer = 0 To DgvLeft.Columns.Count - 1
fields(j) = DgvLeft.SelectedRows(i).Cells(DgvLeft.Columns(j).Name).Value
Next
'delete the row in datagrid Left
ind = DgvLeft.SelectedRows(i).Index
If ind > 0 Then
DgvLeft.Rows.RemoveAt(ind)
Else
DgvLeft.Rows.Remove(DgvLeft.SelectedRows(i))
End If
'add the row in datagrid Right
DgvRight.Rows.Add(fields)
Next

在上面的代码片段中,我尝试在将这一行的值数组添加到另一个数据网格之前删除一行。当我查看"删除"按钮的代码时,我尝试在将值数组添加到另一个数据网格后删除该行。

所以我将这段代码移到了添加值数组的代码下面,它起作用了。索引异常可能是由数组而不是数据网格视图引发的。

最新更新