ListView コントロールの ListView.CheckedItems プロパティを使ってチェックされた項目を取得すると、ArgumentOutOfRangeException 例外がスローされる場合がある

現象

ListView コントロールを使用する Windows フォーム アプリケーションにおいて、ListView.CheckedItems.Count によりチェックされた項目の数を取得すると、ArgumentOutOfRangeException 例外がスローされる場合があります。

この例外が適切にハンドルされていない場合、アプリケーションはエラー ダイアログを表示して終了します。

アプリケーションのコンポネントで、ハンドルされていない例外が発生しました。[続行]をクリックすると、アプリケーションはこのエラーを無視し、続行しようとします。[終了]をクリックすると、アプリケーションは直ちに終了します。
'-1' の InvalidArgument=Value は 'index' に対して有効ではありません。
パラメーター名:Index

原因

この現象は以下のような条件が重なる場合に発生します。

・ ListView コントロールをモーダル ダイアログに表示しており、ダイアログを閉じた後にもう一度開き直す

・ リストビューにソート処理を追加している

・ リストに項目を追加するが、その際、ソートが発生するよう項目の名称を逆順にするなどしておく

・ 追加した項目のチェック ボックスにチェックがある


チェックされている、されていないといったそれぞれの項目の状態を示すインデックスが用意できていないタイミングで ListView.CheckedItems.Count によりチェックされた項目の数を取得しようとすると、ListView コントロールは System.ArgumentOutOfRangeException 例外をスローします。

解決方法

この問題を解決するには、以下のいずれかの方法を使用します。

回避方法 1 : ListViewのフォームをクローズする前に、ListViewのアイテムをクリアします。この回避方法によって、フォームをクローズする前にコントロールからすべてのアイテムを一旦削除します。ListViewのフォームを再度表示する時に、コントロールにすべてのアイテムを新規に作成します。

以下のサンプルコードでは、button1_Click イベント ハンドラー内で ListView コントロールのフォームをクローズする前に、Items.Clear メソッドを呼び出して ListView のアイテムをクリアします。

private void button1_Click(object sender, System.EventArgs e)
{
listView1.Items.Clear();
this.Close();
}
回避方法 2 : ListView.CheckedItems.Count の処理に対する System.ArgumentOutOfRangeException 例外を try/catch を使用してハンドルします。

以下のサンプルコードでは、項目のチェック状態が変更されると発生するイベント ハンドラー内で、System.ArgumentOutOfRangeException 例外をハンドルします。

private void listView1_ItemChecked(object sender, ItemCheckedEventArgs e)
{
try
{
Console.WriteLine(listView1.CheckedItems.Count);
}
catch (System.ArgumentOutOfRangeException ex)
{
Console.WriteLine(ex.Message);
}
}


プロパティ

文書番号:2856712 - 最終更新日: 2016/09/29 - リビジョン: 1

フィードバック