英語で読む

次の方法で共有


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

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

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

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

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

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

  • 共有行の使用

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

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

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

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

  • 個々の DataGridViewCell または DataGridViewRow オブジェクトのセル スタイル プロパティは設定しないでください。 これには、RowTemplate プロパティで指定された行オブジェクトが含まれます。 行テンプレートから複製された新しい行はそれぞれ、テンプレートのセル スタイル オブジェクトの独自のコピーを受け取ります。 スケーラビリティを最大限に高めるには、DataGridView レベルでセル スタイルのプロパティを設定します。 たとえば、DataGridViewCell.Style プロパティではなく、DataGridView.DefaultCellStyle プロパティを設定します。

  • 一部のセルで既定の書式設定以外の書式設定が必要な場合は、セル、行、または列のグループ間で同じ DataGridViewCellStyle インスタンスを使用します。 個々のセル、行、列に DataGridViewCellStyle 型のプロパティを直接設定しないでください。 セル スタイルの共有の例については、「方法: Windows フォーム DataGridView コントロールの既定のセル スタイルを設定する」を参照してください。 また、CellFormatting イベント ハンドラーを処理することで、セル スタイルを個別に設定するときにパフォーマンスの低下を回避することもできます。 例については、「方法: Windows フォーム DataGridView コントロールでデータの書式設定をカスタマイズする」を参照してください。

  • セルのスタイルを決定するときは、DataGridViewCell.Style プロパティではなく、DataGridViewCell.InheritedStyle プロパティを使用します。 Style プロパティにアクセスすると、プロパティがまだ使用されていない場合は、DataGridViewCellStyle クラスの新しいインスタンスが作成されます。 さらに、一部のスタイルが行、列、またはコントロールから継承されている場合、このオブジェクトにはセルの完全なスタイル情報が含まれていない可能性があります。 セル スタイルの継承についての詳細は、「Windows フォーム DataGridView コントロールのセル スタイル 」を参照してください。

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

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

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

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

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

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

詳細については、「Windows Forms 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 メソッドの Add(DataGridViewRow) オーバーロード、AddRange メソッド、Insert メソッドの Insert(Int32,DataGridViewRow) オーバーロード、および DataGridView.Rows コレクションの InsertRange メソッドを呼び出すときに、指定した行を共有できることを確認してください。

行が共有されているかどうかを確認するには、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) オーバーロードを呼び出さないでください。 カスタム比較子を使用して並べ替えた場合、すべての行が共有解除されます。

参照