2008年11月26日水曜日

[.NET]DataGridViewのデータについて

前記事でVC++ 2008 ExpressでDataGridViewにDataSetをバインドする方法について書いたが、その後DataGridViewを操作しようとしたところ、多少はまってしまった。ドキュメントを読んでわかったことだが、DataGridViewと表示・編集しようとしているデータとの関係について書いてみることにする。

DataGridViewに表示されるデータがどこにあるのか、という意味で3つのパターンがある。

普通のモード
普通という言い方が正しいかどうかはわからないが、単にDataGridViewのインスタンスを生成した場合の状態で、対象となるデータはDataGridViewの中に存在する。具体的には、DataGridView.RowsプロパティであるDataGridViewRowCollectionの中に行のデータが格納されている。
バインディングモード
これは、前記事で書いた、DataSetなどに存在するデータをDataGridViewに表示・編集する方法で、具体的には、DataGridView.DataSourceプロパティにデータの実体があるオブジェクトを設定する。VC++やVC#のIDEでデータデザイナとフォームデザイナを使った場合には、これらの設定はIDEによってコード化されるので、特にコードを書く必要はない。
仮想モード
このモードについては、MSDNなどのドキュメントにいろいろ書かれているので、詳細はそちらへ譲るが、基本的にはDataGridViewが表示・編集のためにデータの参照・設定が必要になった場合、イベントが発生する。そのイベントの処理でデータを受け渡しなどをする。この場合、データの実体はプログラマー任せとなる。

実際には、編集などではもっと複雑なデータのやりとりをするようだが、特殊なことをしない限り、あまり意識する必要はないもよう。この手のことは、DataGridViewのドキュメントの中に「共有モード」という記述があるので、それを参照されたい。

ここのでポイントは、バインディングや仮想モードになっているときには、DataGridView.Rowsプロパティにデータが存在しないということである。要するにこのプロパティを使ってデータを操作しているドキュメント上のサンプルなどは、普通のモードで動いているDataGridViewでの話であって、バインディングなどの場合には通用しない。

ところで、バインディングの場合、DataSourceは、基本的にはBindingSourceのインスタンスを設定する。このBindingSourceに実際のデータをBindingSource.DataSourceに設定する。このことは、ドキュメントに詳しく書かれているので詳細は割愛するが、BindingSource.DataSourceには、DataSetなどの複雑な構造のデータや、単純なオブジェクトのリスト(System.Collections.Generic.Listなど)を設定することができる。

DataGridViewで編集などをする場合には、行やセルの選択をいう操作が必要になるのだが、BindingSource.DataSourceに設定されるデータは、列挙可能(IListが実装されている)なものでしかないので、選択された位置という情報は持っていない。すなわち、BindingSourceが選択や項目の並び替え(ソート)を担っているということになる。

プログラムで項目を選択したい場合、普通のモードのDataGridViewときには、Rowsプロパティから行に対するデータを取得して、セルや行(Row)に対して選択を設定する。ところが、バインディングモードの場合、DataGridView.Rowsプロパティを使うのではなく、DataSourceプロパティに設定されたBindingSourceを操作する。具体的にはPositionプロパティやMoveFirstメソッドなどで現在の位置を変更する。

DataGridView.DataSourceにBindingSourceを設定している場合、プログラムでBindingSourceの現在の位置を変更すると、DataGridViewの表示上の選択位置が変更され、マウス操作などでDataGridViewの選択位置が変更されるとBindingSourceの現在の位置が変更される、という仕組みになっている。

0 件のコメント: