C Sharpのコントロール - DataGridViewの仮想モード

提供:MochiuWiki - SUSE, Electronic Circuit, PCB
ナビゲーションに移動 検索に移動

概要

DataGridViewコントロール(表形式でデータの表示および編集を可能とするコントロール)において、膨大なデータを扱う場合、仮想モード(VirtualMode)を使用する。


仮想モード(VirtualMode)とは

仮想モード(VirtualMode)は、DataGridViewコントロールのモードであり、プロパティから設定可能である。

VirtualModeプロパティとは、DataGridViewコントロールのVirtualModeプロパティをtrueにすることにより、
セルに表示するデータを設定する処理と、セルの値が変更された際にデータを格納する処理を自分で実装することができる。

  • メリット
    仮想モード(VirtualMode)は、大規模なデータを使用するためにデザインされており、膨大のデータの取り扱いにおいて、高速かつメモリ使用量の少ないコンパクトな処理にすることができる。

  • デメリット
    セルに表示する値の設定や、セルへの入力値の処理等をユーザが作成する必要がある。



仮想モード(VirtualMode)の実装

DataGridViewコントロールのプロパティの設定

仮想モード(VirtualMode)は、DataGridViewコントロールのVirtualModeプロパティをtrueに設定することにより、有効化する。

DataGridView VirtualMode 1.png


CellValueNeededイベントハンドラの実装

CellValueNeededイベントハンドラは、セルを書式設定して表示するため、DataGridViewコントロールがセルの値を必要とする場合に発生するイベントである。
このイベントにより、セルにデータを表示する。

以下の例では、1行分のデータを持つ簡単なクラスのリスト(DataList)から値を表示している。
ただし、ユーザによる行の追加や削除を考慮していないことに注意すること。

 private void VirtualModeDataGridView_CellValueNeeded(object sender, DataGridViewCellValueEventArgs e)
 {
    if(e.RowIndex > DataList.Count - 1)
    {
       return;
    }
 
    switch(e.ColumnIndex)
    {
       case 0:
          e.Value = DataList[e.RowIndex].Data1;
          break;
       case 1:
          e.Value = DataList[e.RowIndex].Data2;
          break;
       case 2:
          e.Value = DataList[e.RowIndex].Data3;
          break;
       case 3:
          e.Value = DataList[e.RowIndex].Data4;
          break;
       case 4:
          e.Value = DataList[e.RowIndex].Data5;
          break;
       default:
          e.Value = null;
          break;
    }
 }


CellValuePushedイベントハンドラの実装

CellValuePushedイベントハンドラは、セルの値が変更された時に発生するイベントである。
これにより、DataGridViewコントロールに表示しているデータの実体に対して、変更を反映する。

以下の例では、1行分のデータを持つ簡単なクラスのリスト(DataList)の値を変更している。
ただし、上記の例と同様、ユーザによる行の追加や削除を考慮していないことに注意すること。

 private void VirtualModeDataGridView_CellValuePushed(object sender, DataGridViewCellValueEventArgs e)
 {
    switch (e.ColumnIndex)
    {
       case 0:
          int nVal;
          if (int.TryParse(e.Value.ToString(),out nVal))
          {
             DataList[e.RowIndex].Data1 = nVal;
          }
          break;
       case 1:
          DataList[e.RowIndex].Data2  = e.Value.ToString();
          break;
       case 2:
          DataList[e.RowIndex].Data3 = e.Value.ToString();
          break;
       case 3:
          DateTime DateVal;
          if (DateTime.TryParse(e.Value.ToString(), out DateVal))
          {                        
             DataList[e.RowIndex].Data4 = DateVal;
          }
          break;
       case 4:
          Byte bVal;
          if (Byte.TryParse(e.Value.ToString(), out bVal))
          {
             DataList[e.RowIndex].Data5 = bVal;
          }
          break;
       default:
          break;
    }
 }


NewRowNeededイベントハンドラの実装

NewRowNeededイベントハンドラは、ユーザがDataGridViewコントロールの新しい行に移動した時に発生するイベントである。
これは、ユーザに行の追加を許可する場合に必要となる。

注意点として、ユーザが新しい行に移動するごとにNewRowNeededイベントが発生するため、
DataGridViewコントロールに表示しているデータに新しい行のデータを追加する場合、ユーザが新しい行に移動および編集せずに他の行に移動等の操作をした時に余分なデータが追加される。

そのため、ユーザに行の追加を許可する場合は、編集中の行のデータを全体のデータと別に持ち、
RowValidatedイベントハンドラで編集を反映するタイミングで編集を反映および追加する等の処理が必要となる。

詳細を知りたい場合は、Microsoftの公式WebサイトにあるVirtualMode実装のチュートリアルを参照すること。
チュートリアル : Windowsフォーム DataGridViewコントロールでの仮想モードの実装
https://docs.microsoft.com/ja-jp/dotnet/framework/winforms/controls/implementing-virtual-mode-wf-datagridview-control

RowDirtyStateNeededイベントハンドラ

RowDirtyStateNeededイベントハンドラは、現在の行がコミットされていない変更を含んでいるかどうかを決定しなければならない時に発生するイベントである。
例えば、セルの選択が別の行に移る場合、および、行ヘッダにカーソルが移動した場合等である。

CancelRowEditイベントハンドラ

CancelRowEditイベントハンドラは、行の編集をキャンセルした場合(セルの編集中にESCキーを押下する等)に発生するイベントである。
これは、編集をキャンセルする場合、特別な動作をする必要がある時に実装が必要となる。

例えば、NewRowNeededイベントハンドラを実装するため、編集中の行のデータを全体のデータと別に持っている場合、
編集をキャンセルした時に編集中の行のデータを破棄する処理を実装する。

実装しない場合においても、セルの編集中に[ESC]キーを押下すれば、そのセルの編集はキャンセルされる。