modest violet

modest violet

開発者としてのあれこれや、日々の雑記など

your future hasn't written yet. no one's has.
by Emmett Lathrop "Doc" Brown

DataGridViewで行にデータがあるのに、「インデックス -1に値がありません。」というエラーが発生する件の解決法

久々にVB.NETのDataGridViewでハマりました・・・。グリッドには正しくDataSourceで渡した結果が表示されているのですが、表示された行をクリックしようとすると

インデックス -1に値がありません。

と不可思議なIndexOutOfRangeExceptionエラーが発生します。いやいや、行表示されているじゃないですかぁ・・・。
f:id:shin21sk:20160311215246p:plain

発生するタイミング

現在のコードはこんな感じ。
HogeListクラスの結果を hogeLists に格納して DataSource にバインドしています。

' 敢えての初期化
myDataGridView.DataSource = New List(Of HogeList)
' 実際のデータをセットする
myDataGridView.DataSource = hogeLists  

普段はこれで問題なく動作します。が、とある条件の場合だけおかしな状況に陥ってしまいます。
検証した結果、最初に値が0件(NewしただけのhogeLists)をDataSourceにバインドすると発生するようです。

myDataGridView.DataSource = New List(Of HogeList)
' hogeLists がNewした直後の場合、おかしくなるトリガー
myDataGridView.DataSource = hogeLists  

一度発生すると、一旦Newで初期化してもうんともすんとも言いません。ああ、困った。。。

回避策を施す

回避策として、初期化直後の0件の場合はDataSourceにバインドしないだけ!という非常にシンプルな方法で対応出来ました。

' 敢えての初期化
myDataGridView.DataSource = New List(Of HogeList)
myDataGridView.Refresh()
' 実際のデータをセットする。でもNewした直後や0件の場合は処理しない
if hogeLists.Count > 0 Then
    myDataGridView.DataSource = hogeLists
    myDataGridView.Refresh()
end if

ここにたどり着くまでに紆余曲折はありましたが・・・。いつもトラブル回避ってシンプルに対応出来る事が多いんですよね。