2008年07月15日
DataGridView(.Net Fw2.0)の不具合
[タイトル]
DataGridView のソートにて NullReferenceException が発生
[お問い合わせの概要]
DataGridView の列名をクリックしてソートしようとした際に、以下のエラーが発生する場合がある。
-----
NullReferenceException はハンドルされませんでした。
オブジェクト参照がオブジェクトインスタンスに設定されていません。
-----
- 発生条件など
DataGridView で横スクロールバーが表示されている状態で、スクロールを一番右に移動させた後、列名をクリックした場合にエラーとなる。
データが 120 バイト(半角の a を 120 個並べたデータ)の場合では 100%エラーが発生する
横スクロールバーが一番左にある状態で列名をクリックした場合はエラーにならない。
横スクロールバーはデータが長い場合に表示され、DataGridView 全体に表示されるものである。
横スクロールバーが表示されても、1つのセルのデータ長が短いと、エラーにならない。
[回答]
ご提供いただきましたサンプルにより現象を確認いたしました。
本現象について調査を実施した結果、弊社にて確認している製品の不具合に該当していることを確認いたしました。
弊社製品の不具合により御社に大変ご迷惑をおかけしましたことを深くお詫び申し上げます。
- 原因について
DataGridView において列の自動調整が有効な状態で、本現象の発生条件となる操作を行った場合、DataGridView 内部では表示内容を更新するために、内部プロパティ等の調整処理が行われております。
しかし、この調整処理に問題があり、列幅について複数の内部処理の間で不整合が発生し、お問い合わせの例外が発生している状況でございます。
- 回避策について
本現象につきましては、現時点では修正されたモジュールなどが存在していない状況でございます。
そのため、アプリケーション側での回避策を実装していただく必要がございます。
具体的には、DataGridView クラスの継承クラスを作成していただき、以下の処理を追加していただく必要がございます。
・HorizontalScrollBar.Scroll イベントのイベント ハンドラの追加
・OnColumnWidthChanged() メソッドのオーバーライド
-> 上記の各メソッド内での列幅に関するプロパティ (DataGridViewColumn.MinimumWidth) の更新を行います
・OnColumnHeaderMouseClick() メソッドのオーバーライド
-> 上記回避策を実装することで表示のオフセットにソート前後でずれが生じるため、明示的に表示位置を修正します
なお、これらの回避策を実装することで 1ソート時の表示が複数回更新される結果となりますので、画面にちらつきが発生します。
その防止のため、LockWindowUpdate API の呼び出しによる一時的な表示更新のロック処理を含めさせていただいております。