次の方法で共有


Windows フォーム DataGridView コントロールのスケーリングに関するベスト プラクティス

DataGridView コントロールは、最大のスケーラビリティを提供するように設計されています。 大量のデータを表示する必要がある場合は、大量のメモリを消費したり、ユーザー インターフェイス (UI) の応答性を低下させたりしないように、このトピックで説明されているガイドラインに従う必要があります。 このトピックでは、次の問題について説明します。

  • セル スタイルを効率的に使用する

  • ショートカット メニューを効率的に使用する

  • 自動サイズ変更を効率的に使用する

  • 選択したセル、行、列のコレクションを効率的に使用する

  • 共有行の使用

  • 行の共有が解除されないようにする

特別なパフォーマンスニーズがある場合は、仮想モードを実装し、独自のデータ管理操作を提供できます。 詳細については、「 Windows フォーム DataGridView コントロールのデータ表示モード」を参照してください。

セル スタイルを効率的に使用する

各セル、行、列には、独自のスタイル情報を含めることができます。 スタイル情報は、 DataGridViewCellStyle オブジェクトに格納されます。 多数の個々の DataGridView 要素に対してセル スタイル オブジェクトを作成すると、特に大量のデータを操作する場合に非効率的になる可能性があります。 パフォーマンスへの影響を回避するには、次のガイドラインを使用します。

ショートカット メニューの効率的な使用

各セル、行、列には、独自のショートカット メニューを使用できます。 DataGridView コントロールのショートカット メニューは、ContextMenuStrip コントロールによって表されます。 セル スタイル オブジェクトと同様に、多数の個別の DataGridView 要素のショートカット メニューを作成すると、パフォーマンスに悪影響が及びます。 このペナルティを回避するには、次のガイドラインを使用します。

  • 個々のセルと行のショートカット メニューは作成しないでください。 これには、新しい行がコントロールに追加されたときにショートカット メニューと共に複製される行テンプレートが含まれます。 スケーラビリティを最大限に高めるために、コントロールの ContextMenuStrip プロパティのみを使用して、コントロール全体の 1 つのショートカット メニューを指定します。

  • 複数の行またはセルに対して複数のショートカット メニューが必要な場合は、 CellContextMenuStripNeeded または RowContextMenuStripNeeded イベントを処理します。 これらのイベントを使用すると、ショートカット メニュー オブジェクトを自分で管理し、パフォーマンスを調整できます。

自動サイズ変更機能を効率的に使用する

セルの内容が変更されると、行、列、ヘッダーのサイズを自動的に変更して、セルの内容全体がクリッピングなしで表示されるようにすることができます。 サイズ変更モードを変更すると、行、列、ヘッダーのサイズを変更することもできます。 適切なサイズを決定するには、 DataGridView コントロールが対応する必要がある各セルの値を調べる必要があります。 大規模なデータ セットを操作する場合、この分析は、自動サイズ変更が発生したときにコントロールのパフォーマンスに悪影響を与える可能性があります。 パフォーマンスの低下を回避するには、次のガイドラインに従ってください。

詳細については、「 Windows フォーム DataGridView コントロールのサイズ設定オプション」を参照してください。

選択したセル、行、列のコレクションを効率的に使用する

SelectedCells コレクションは、大規模な選択では効率的に実行されません。 SelectedRowsコレクションとSelectedColumns コレクションは非効率的な場合もありますが、一般的なDataGridView コントロールのセルよりも行数が少なく、行数よりも列数が少なくなるため、効率が低くなります。 これらのコレクションを操作するときのパフォーマンスの低下を回避するには、次のガイドラインを使用します。

共有行の使用

DataGridViewコントロールでは、共有行を介して効率的なメモリ使用が実現されます。 行は、 DataGridViewRow クラスのインスタンスを共有することで、外観と動作に関する情報をできるだけ多く共有します。

行インスタンスを共有するとメモリが節約されますが、行は簡単に共有解除される可能性があります。 たとえば、ユーザーがセルと直接対話するたびに、その行は非共有になります。 これは回避できないため、このトピックのガイドラインは、非常に大量のデータを操作する場合、およびユーザーがプログラムを実行するたびに比較的少量のデータを操作する場合にのみ役立ちます。

セルに値が含まれている場合、バインドされていない DataGridView コントロールで行を共有することはできません。 DataGridView コントロールが外部データ ソースにバインドされている場合、または仮想モードを実装して独自のデータ ソースを提供する場合、セル値はセル オブジェクトではなくコントロールの外部に格納され、行を共有できます。

行オブジェクトを共有できるのは、そのすべてのセルの状態を、行の状態とセルを含む列の状態から判断できる場合のみです。 セルの状態を変更して、その行と列の状態から推測できないようにすると、その行を共有できなくなります。

たとえば、次の状況では行を共有できません。

  • この行には、選択した列に含まれていない選択されたセルが 1 つ含まれています。

  • 行には、 ToolTipText プロパティまたは ContextMenuStrip プロパティが設定されたセルが含まれています。

  • 行には、DataGridViewComboBoxCell が含まれており、その Items プロパティが設定されています。

バインド モードまたは仮想モードでは、 CellToolTipTextNeeded イベントと CellContextMenuStripNeeded イベントを処理することで、個々のセルのツールヒントとショートカット メニューを提供できます。

DataGridView コントロールは、DataGridViewRowCollectionに行が追加されるたびに、共有行の使用を自動的に試行します。 行が共有されるようにするには、次のガイドラインを使用します。

  • Add メソッドのAdd(Object[]) オーバーロードと、DataGridView.Rows コレクションのInsert メソッドのInsert(Object[])オーバーロードを呼び出さないようにします。 これらのオーバーロードにより、共有されていない行が自動的に作成されます。

  • 次の場合は、 DataGridView.RowTemplate プロパティで指定された行を共有できることを確認してください。

  • DataGridView.Rows コレクションのAddCopyAddCopiesInsertCopy、およびInsertCopiesメソッドを呼び出すときに、indexSource パラメーターによって示される行を共有できることを確認します。

  • Add メソッド、AddRange メソッド、Insert メソッドのInsert(Int32,DataGridViewRow) オーバーロード、およびDataGridView.Rows コレクションのInsertRange メソッドのAdd(DataGridViewRow)オーバーロードを呼び出すときに、指定した行を共有できることを確認してください。

行が共有されているかどうかを確認するには、 DataGridViewRowCollection.SharedRow メソッドを使用して行オブジェクトを取得し、オブジェクトの Index プロパティを確認します。 共有行の Index プロパティ値は常に -1 です。

行の共有が解除されないようにする

共有行は、コードまたはユーザーアクションの結果として共有解除される可能性があります。 パフォーマンスへの影響を回避するには、行の共有が解除されないようにする必要があります。 アプリケーションの開発中に、 RowUnshared イベントを処理して、行がいつ非共有になるかを判断できます。 これは、行共有の問題をデバッグするときに便利です。

行が共有されなくなるのを防ぐには、次のガイドラインを使用します。

  • Rows コレクションのインデックスを作成したり、foreach ループで反復処理したりしないでください。 通常、行に直接アクセスする必要はありません。 DataGridView 行を操作するメソッドは、行インスタンスではなく行インデックス引数を受け取ります。 さらに、行関連イベントのハンドラーは、行のプロパティを持つイベント引数オブジェクトを受け取ります。このオブジェクトを使用すると、行を非共有にすることなく行を操作できます。

  • 行オブジェクトにアクセスする必要がある場合は、 DataGridViewRowCollection.SharedRow メソッドを使用し、行の実際のインデックスを渡します。 ただし、このメソッドを使用して取得した共有行オブジェクトを変更すると、このオブジェクトを共有するすべての行が変更されることに注意してください。 ただし、新しいレコードの行は他の行と共有されないため、他の行を変更しても影響を受けなくなります。 また、共有行によって表される行によってショートカット メニューが異なる場合があることにも注意してください。 共有行インスタンスから適切なショートカット メニューを取得するには、 GetContextMenuStrip メソッドを使用し、行の実際のインデックスを渡します。 代わりに共有行の ContextMenuStrip プロパティにアクセスすると、-1 の共有行インデックスが使用され、正しいショートカット メニューは取得されません。

  • DataGridViewRow.Cells コレクションのインデックス作成は避けてください。 セルに直接アクセスすると、親行が共有されなくなり、新しい DataGridViewRowがインスタンス化されます。 セル関連のイベントのハンドラーは、セルのプロパティを持つイベント引数オブジェクトを受け取ります。このオブジェクトを使用すると、行を共有解除せずにセルを操作できます。 CurrentCellAddress プロパティを使用して、セルに直接アクセスせずに、現在のセルの行インデックスと列インデックスを取得することもできます。

  • セルベースの選択モードは避けてください。 これらのモードにより、行が非共有になります。 代わりに、 DataGridView.SelectionMode プロパティを DataGridViewSelectionMode.FullRowSelect または DataGridViewSelectionMode.FullColumnSelect に設定します。

  • DataGridViewRowCollection.CollectionChangedまたはDataGridView.RowStateChangedイベントを処理しないでください。 これらのイベントにより、行が非共有になります。 また、これらのイベントを発生させる DataGridViewRowCollection.OnCollectionChanged または DataGridView.OnRowStateChanged メソッドを呼び出さないでください。

  • DataGridView.SelectionMode プロパティの値がFullColumnSelectColumnHeaderSelectFullRowSelect、またはRowHeaderSelectされている場合は、DataGridView.SelectedCells コレクションにアクセスしないでください。 これにより、選択したすべての行が共有解除されます。

  • DataGridView.AreAllCellsSelected メソッドを呼び出さないでください。 このメソッドを使用すると、行が共有解除される可能性があります。

  • DataGridView.SelectionMode プロパティ値がCellSelectされている場合は、DataGridView.SelectAll メソッドを呼び出さないでください。 これにより、すべての行が非共有になります。

  • 列内の対応するプロパティがtrueに設定されている場合は、セルのReadOnlyまたはSelectedプロパティをfalseに設定しないでください。 これにより、すべての行が非共有になります。

  • DataGridViewRowCollection.List プロパティにはアクセスしないでください。 これにより、すべての行の共有が解除されます。

  • Sort メソッドのSort(IComparer)オーバーロードを呼び出さないでください。 カスタム比較子を使用して並べ替えた場合、すべての行が共有解除されます。

こちらも参照ください