2016-04-29 136 views
3

誰かがこれを複製として習得する前に、私は実際に問題を解決するためにStackOverflowとGoogleの両方を検索しましたが、いずれも成功していません。DataGridView - インデックスが範囲外です。

要約すると:私は、CSコース「オブジェクト指向プログラミング」のユニットの一部としてゲームを構築しています。このゲームの目的は、無作為にタイマーを使用して燃料レベルを差し引いた後、燃料がゼロに達したときにクラッシュなどのイベントを発生させるプレーンを生成することです。次に、プレーンに着陸させて滑走路を割り当てる必要があります。

これはすべてうまくいきますが、私は生成されているすべてのプレーンをリストし、ユーザーにそれらのオプションを与える必要がある段階にあります。

最初はListViewを使用しましたが、ボタンを列として使用したいので、すぐにDataGridViewに切り替えました。

私は、選択した行の中の "Land Plane"ボタンをクリックするたびに、プレーンが生成され、さらにDataGridView内に表示されるので、選択範囲は最初の行に単純にジャンプします。私は担任のために私の講師に尋ねました、そして、彼は、燃料の価値は絶えず更新されていると言いました。 DataGridViewがクリアされると、選択された行がリセットされます。

これを解決するために、選択した行と選択した列を格納する2つのローカル変数を追加しました。 「Land Plane」ボタンがクリックされたときに、選択した列がまだコレクション内に残っているかどうかを確認しました。これは、燃料が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 

誰もが実際にこれを引き起こしているものにいくつかの光を当てることができればエラー私は最も感謝しています。

+2

あなたは ' –

+0

である可能性がある' selCol'をチェックしていません。特に '-1'に初期化されています。 – Plutonix

+0

@Matt Kent例外が発生したときの' selCol'と 'selRow'の値は何ですか?それはあなたの問題について多くの光を当てるはずです。 – vbnet3d

答えて

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 >= 0 And selRow <= DataGridView1.Rows.Count - 1 Then 
     DataGridView1.CurrentCell = DataGridView1.Rows(selRow).Cells(1) 
End If 

この新しいコードに

If selRow <> -1 And selRow <= DataGridView1.Rows.Count - 1 Then 
    DataGridView1.CurrentCell = DataGridView1.Rows(selRow).Cells(selCol) 
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 

単に削除して追加するのではなく、追加/更新する必要があります。

+1

あなたの答えをありがとう、それはエラーを修正しました。しかし、正しい行を再選択しないという私の最初の問題に戻るようになりました。単にDataGridViewの最初の行にジャンプします。何か案は? –

+0

'selCol'と' selRow'はどこで宣言しましたか?それが "モジュールレベル"の場合、値は引き継がれますが、この 'Sub'内で宣言されていれば、毎回リセットされます。 – vbnet3d

+1

「Public Class Game」の下に直接宣言されています。したがって、モジュールレベル。 –

関連する問題