在任何人将此作为副本进行分类之前,我确实在StackOverflow和Google周围搜索了我的问题的解决方案,但事实证明这两者都没有成功。
总结一下:我正在构建一个游戏,作为我CS课程中的一个单元的一部分"面向对象编程"。游戏的目的是随机生成飞机,使用计时器扣除燃油油位,然后在燃油达到0时发生碰撞等事件。然后我们必须降落飞机并为它们分配跑道,等等在......
这一切都很好,但是,我正处于我必须列出正在生成的所有平面的阶段,然后让用户选择降落它们。
我最初使用ListView但很快切换到DataGridView,因为我想将一个按钮作为列。
因此,当我点击" Land Plane"时,在生成平面时,并且在DataGridView中进一步显示这些平面。我选择的行中的按钮选择只会跳回到第一行。我向我的讲师询问了他的帮助,他说这是因为燃料的价值随着倒计时不断更新。清除DataGridView后,所选行将重置。
为了解决这个问题,我们添加了两个局部变量来存储选定的行和选定的列。我们检查了所选列是否仍然保留在集合中,当地平面"单击按钮。这是因为当燃料达到0时,它只是从DataGridView中删除该行。
我现在遇到的问题是,我的讲师很困惑的是:
未处理的类型' System.ArgumentOutOfRangeException' 发生在mscorlib.dll
其他信息:指数超出范围。必须是非负面的 并且小于集合的大小。
处理DataGridView的代码如下:
Public Sub populateDataGV()
Dim p As New Aircraft
selRow = -1
'Populate the data grid view
If Not (IsNothing(DataGridView1.CurrentCell)) Then
selRow = DataGridView1.CurrentCell.RowIndex
selCol = DataGridView1.CurrentCell.ColumnIndex
End If
DataGridView1.Rows.Clear()
DataGridView1.ColumnCount = 2
DataGridView1.Columns(0).Name = "Flight No"
DataGridView1.Columns(1).Name = "Fuel"
For Each p In airport.planeCollection
Dim row As String() = New String() {p.name, p.getFuelLevel()}
DataGridView1.Rows.Add(row)
Next
Dim RowsToDelete As New List(Of DataGridViewRow)()
For Each rows As DataGridViewRow In DataGridView1.Rows
If rows.Cells(1).Value IsNot Nothing AndAlso rows.Cells(1).Value.ToString = "0" Then
RowsToDelete.Add(rows)
If selRow = rows.Index Then
selRow = -1
End If
End If
Next
For Each rows As DataGridViewRow In RowsToDelete
DataGridView1.Rows.Remove(rows)
Next
RowsToDelete.Clear()
If selRow <> -1 And selRow <= DataGridView1.Rows.Count - 1 Then
DataGridView1.CurrentCell = DataGridView1.Rows(selRow).Cells(selCol)
End If
'Add button column
Dim btn As DataGridViewButtonColumn = New DataGridViewButtonColumn()
btn.HeaderText = "Action"
btn.Text = "Land Plane"
btn.UseColumnTextForButtonValue = True
DataGridView1.Columns.Add(btn)
End Sub
这是抛出错误的地方:
If selRow <> -1 And selRow <= DataGridView1.Rows.Count - 1 Then
DataGridView1.CurrentCell = DataGridView1.Rows(selRow).Cells(selCol)
End If
如果有人能够了解实际导致此错误的原因,我将非常感激。
答案 0 :(得分:2)
您的范围检查可能会出错。
首先,您当前的代码允许selRow小于-2:
If selRow <> -1 And selRow <= DataGridView1.Rows.Count - 1 Then
DataGridView1.CurrentCell = DataGridView1.Rows(selRow).Cells(selCol)
End If
其次,您不需要设置列...而是将其设置为0或1。
你应该改变
If selRow <> -1 And selRow <= DataGridView1.Rows.Count - 1 Then
DataGridView1.CurrentCell = DataGridView1.Rows(selRow).Cells(selCol)
End If
到
If selRow >= 0 And selRow <= DataGridView1.Rows.Count - 1 Then
DataGridView1.CurrentCell = DataGridView1.Rows(selRow).Cells(1)
End If
这个新代码正确地检查两个值。
此外,您需要从顶部删除:
selRow = -1
最后,为了解决选择正确行的问题,我建议改变:
DataGridView1.Rows.Clear()
DataGridView1.ColumnCount = 2
DataGridView1.Columns(0).Name = "Flight No"
DataGridView1.Columns(1).Name = "Fuel"
For Each p In airport.planeCollection
Dim row As String() = New String() {p.name, p.getFuelLevel()}
DataGridView1.Rows.Add(row)
Next
为:
' DataGridView1.Rows.Clear()
If DataGridView1.ColumnCount = 0 Then
DataGridView1.ColumnCount = 2
DataGridView1.Columns(0).Name = "Flight No"
DataGridView1.Columns(1).Name = "Fuel"
End If
For Each p In airport.planeCollection
Dim updated As Boolean = False
For Each rows As DataGridViewRow In DataGridView1.Rows
If rows.Cells(0).Value = p.name Then
rows.Cells(1).Value = p.getFuelLevel
updated = True
Exit For
End If
Next
If Not updated Then
Dim row As String() = New String() {p.name, p.getFuelLevel()}
DataGridView1.Rows.Add(row)
End If
Next
您应该添加/更新,而不是简单地清除和添加。