Windows フォーム DataGridView コントロールを拡張するための推奨される手順Best Practices for Scaling the Windows Forms DataGridView Control

DataGridView コントロールは、最大のスケーラビリティを提供するように設計されています。The DataGridView control is designed to provide maximum scalability. 大量のデータを表示する必要がある場合は、このトピックで説明されているガイドラインに従って、大量のメモリを消費したり、ユーザーインターフェイス (UI) の応答性を低下させたりすることは避けてください。If you need to display large amounts of data, you should follow the guidelines described in this topic to avoid consuming large amounts of memory or degrading the responsiveness of the user interface (UI). このトピックでは、次の問題について説明します。This topic discusses the following issues:

  • セルスタイルの効率的な使用Using cell styles efficiently

  • ショートカットメニューの効率的な使用Using shortcut menus efficiently

  • 自動サイズ変更の効率的な使用Using automatic resizing efficiently

  • 選択したセル、行、および列のコレクションを効率的に使用するUsing the selected cells, rows, and columns collections efficiently

  • 共有行の使用Using shared rows

  • 行が非共有になるのを防ぐPreventing rows from becoming unshared

特別なパフォーマンスのニーズがある場合は、仮想モードを実装し、独自のデータ管理操作を提供できます。If you have special performance needs, you can implement virtual mode and provide your own data management operations. 詳細については、「 Windows フォーム DataGridView コントロールのデータ表示モード」を参照してください。For more information, see Data Display Modes in the Windows Forms DataGridView Control.

セルスタイルの効率的な使用Using Cell Styles Efficiently

各セル、行、および列には、独自のスタイル情報を設定できます。Each cell, row, and column can have its own style information. スタイル情報は DataGridViewCellStyle オブジェクトに格納されます。Style information is stored in DataGridViewCellStyle objects. 特に大量のデータを使用する場合、多くの個別の DataGridView 要素に対してセルスタイルオブジェクトを作成することは非効率的です。Creating cell style objects for many individual DataGridView elements can be inefficient, especially when working with large amounts of data. パフォーマンスへの影響を回避するには、次のガイドラインに従います。To avoid a performance impact, use the following guidelines:

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

各セル、行、および列には、独自のショートカットメニューを設定できます。Each cell, row, and column can have its own shortcut menu. DataGridView コントロールのショートカットメニューは、ContextMenuStrip コントロールによって表されます。Shortcut menus in the DataGridView control are represented by ContextMenuStrip controls. セルスタイルオブジェクトと同様に、多くの個別の DataGridView 要素のショートカットメニューを作成すると、パフォーマンスが低下します。Just as with cell style objects, creating shortcut menus for many individual DataGridView elements will negatively impact performance. このようにペナルティを回避するには、次のガイドラインに従います。To avoid this penalty, use the following guidelines:

  • 個々のセルおよび行のショートカットメニューを作成しないようにします。Avoid creating shortcut menus for individual cells and rows. これには、新しい行がコントロールに追加されたときに、そのショートカットメニューと共に複製される行テンプレートが含まれます。This includes the row template, which is cloned along with its shortcut menu when new rows are added to the control. 最大限のスケーラビリティを実現するには、コントロールの ContextMenuStrip プロパティのみを使用して、コントロール全体に1つのショートカットメニューを指定します。For maximum scalability, use only the control's ContextMenuStrip property to specify a single shortcut menu for the entire control.

  • 複数の行またはセルに複数のショートカットメニューが必要な場合は、CellContextMenuStripNeeded イベントまたは RowContextMenuStripNeeded イベントを処理します。If you require multiple shortcut menus for multiple rows or cells, handle the CellContextMenuStripNeeded or RowContextMenuStripNeeded events. これらのイベントを使用すると、ショートカットメニューオブジェクトを自分で管理できるため、パフォーマンスを調整できます。These events let you manage the shortcut menu objects yourself, allowing you to tune performance.

自動サイズ変更の効率的な使用Using Automatic Resizing Efficiently

セルの内容全体がクリッピングなしで表示されるように、行、列、およびヘッダーをセルの内容の変更に合わせて自動的にサイズ変更することができます。Rows, columns, and headers can be automatically resized as cell content changes so that the entire contents of cells are displayed without clipping. サイズ変更モードを変更すると、行、列、およびヘッダーのサイズも変更される可能性があります。Changing sizing modes can also resize rows, columns, and headers. 正しいサイズを判断するには、DataGridView コントロールで、対応が必要な各セルの値を確認する必要があります。To determine the correct size, the DataGridView control must examine the value of each cell that it must accommodate. 大きなデータセットを使用する場合、自動サイズ変更が発生すると、この分析によってコントロールのパフォーマンスが低下する可能性があります。When working with large data sets, this analysis can negatively impact the performance of the control when automatic resizing occurs. パフォーマンスの低下を回避するには、次のガイドラインに従います。To avoid performance penalties, use the following guidelines:

詳細については、「 Windows フォーム DataGridView コントロールのサイズ変更オプション」を参照してください。For more information, see Sizing Options in the Windows Forms DataGridView Control.

選択したセル、行、および列のコレクションを効率的に使用するUsing the Selected Cells, Rows, and Columns Collections Efficiently

SelectedCells コレクションは、大きな選択によって効率的には実行されません。The SelectedCells collection does not perform efficiently with large selections. SelectedRows コレクションと SelectedColumns コレクションも非効率的ですが、一般的な DataGridView コントロールのセルよりも多くの行があり、行よりも多くの列が少ないため、効率が悪くなります。The SelectedRows and SelectedColumns collections can also be inefficient, although to a lesser degree because there are many fewer rows than cells in a typical DataGridView control, and many fewer columns than rows. これらのコレクションを操作するときのパフォーマンスの低下を回避するには、次のガイドラインに従います。To avoid performance penalties when working with these collections, use the following guidelines:

共有行の使用Using Shared Rows

効率的なメモリ使用は、共有行によって DataGridView 制御で実現されます。Efficient memory use is achieved in the DataGridView control through shared rows. 行は、DataGridViewRow クラスのインスタンスを共有することで、その外観と動作に関する情報を可能な限り共有します。Rows will share as much information about their appearance and behavior as possible by sharing instances of the DataGridViewRow class.

行インスタンスを共有するとメモリが節約されますが、行は簡単に非共有になります。While sharing row instances saves memory, rows can easily become unshared. たとえば、ユーザーが直接セルを操作すると、その行の共有が解除されます。For example, whenever a user interacts directly with a cell, its row becomes unshared. このことは避けられないため、このトピックのガイドラインは、非常に大量のデータを扱う場合、およびプログラムを実行するたびにユーザーが比較的小さなデータの一部を操作する場合にのみ役立ちます。Because this cannot be avoided, the guidelines in this topic are useful only when working with very large amounts of data and only when users will interact with a relatively small part of the data each time your program is run.

セルに値が含まれている場合、バインドされていない DataGridView コントロールで行を共有することはできません。A row cannot be shared in an unbound DataGridView control if any of its cells contain values. DataGridView コントロールが外部データソースにバインドされている場合、または仮想モードを実装して独自のデータソースを指定した場合、セル値はセルオブジェクトではなく、コントロールの外部に格納されるので、行を共有することができます。When the DataGridView control is bound to an external data source or when you implement virtual mode and provide your own data source, the cell values are stored outside the control rather than in cell objects, allowing the rows to be shared.

行オブジェクトを共有できるのは、すべてのセルの状態が行の状態とセルを含む列の状態から決まる場合だけです。A row object can only be shared if the state of all its cells can be determined from the state of the row and the states of the columns containing the cells. 行と列の状態から推測できないようにセルの状態を変更すると、その行を共有することはできません。If you change the state of a cell so that it can no longer be deduced from the state of its row and column, the row cannot be shared.

たとえば、次のような状況では、行を共有することはできません。For example, a row cannot be shared in any of the following situations:

  • この行には、選択された列に含まれていない1つの選択されたセルが含まれています。The row contains a single selected cell that is not in a selected column.

  • この行には、ToolTipText または ContextMenuStrip プロパティが設定されたセルが含まれています。The row contains a cell with its ToolTipText or ContextMenuStrip properties set.

  • この行には、Items プロパティが設定された DataGridViewComboBoxCell が含まれています。The row contains a DataGridViewComboBoxCell with its Items property set.

バインドモードまたは仮想モードでは、CellToolTipTextNeeded イベントと CellContextMenuStripNeeded イベントを処理することによって、個々のセルのツールヒントやショートカットメニューを提供できます。In bound mode or virtual mode, you can provide ToolTips and shortcut menus for individual cells by handling the CellToolTipTextNeeded and CellContextMenuStripNeeded events.

DataGridView コントロールは、行が DataGridViewRowCollectionに追加されるたびに、共有行を自動的に使用しようとします。The DataGridView control will automatically attempt to use shared rows whenever rows are added to the DataGridViewRowCollection. 次のガイドラインを使用して、行が共有されていることを確認します。Use the following guidelines to ensure that rows are shared:

  • Add メソッドの Add(Object[]) オーバーロードと、DataGridView.Rows コレクションの Insert メソッドの Insert(Object[]) オーバーロードを呼び出さないでください。Avoid calling the Add(Object[]) overload of the Add method and the Insert(Object[]) overload of the Insert method of the DataGridView.Rows collection. これらのオーバーロードは、自動的に非共有行を作成します。These overloads automatically create unshared rows.

  • 次の場合は、DataGridView.RowTemplate プロパティで指定された行を共有できることを確認してください。Be sure that the row specified in the DataGridView.RowTemplate property can be shared in the following cases:

  • InsertCopies コレクションの AddCopyAddCopiesInsertCopy、および DataGridView.Rows の各メソッドを呼び出すときに、indexSource パラメーターによって示される行を共有できることを確認してください。Be sure that the row indicated by the indexSource parameter can be shared when calling the AddCopy, AddCopies, InsertCopy, and InsertCopies methods of the DataGridView.Rows collection.

  • Add メソッド、AddRange メソッド、Insert メソッドの Insert(Int32,DataGridViewRow) オーバーロード、および InsertRange コレクションの DataGridView.Rows メソッドの Add(DataGridViewRow) オーバーロードを呼び出すときに、指定された行を共有できることを確認してください。Be sure that the specified row or rows can be shared when calling the Add(DataGridViewRow) overload of the Add method, the AddRange method, the Insert(Int32,DataGridViewRow) overload of the Insert method, and the InsertRange method of the DataGridView.Rows collection.

行が共有されているかどうかを判断するには、DataGridViewRowCollection.SharedRow メソッドを使用して行オブジェクトを取得し、オブジェクトの Index プロパティを確認します。To determine whether a row is shared, use the DataGridViewRowCollection.SharedRow method to retrieve the row object, and then check the object's Index property. 共有行には、常に、Index のプロパティ値が-1 に設定されています。Shared rows always have an Index property value of –1.

行が非共有になるのを防ぐPreventing Rows from Becoming Unshared

共有行は、コードまたはユーザー操作の結果として非共有になることがあります。Shared rows can become unshared as a result of code or user action. パフォーマンスへの影響を回避するには、行が共有されなくなるのを避ける必要があります。To avoid a performance impact, you should avoid causing rows to become unshared. アプリケーションの開発中に、RowUnshared のイベントを処理して、行の共有を解除するタイミングを判断できます。During application development, you can handle the RowUnshared event to determine when rows become unshared. これは、行共有の問題をデバッグする場合に便利です。This is useful when debugging row-sharing problems.

行が非共有にならないようにするには、次のガイドラインに従います。To prevent rows from becoming unshared, use the following guidelines:

  • Rows コレクションにインデックスを作成したり、foreach ループで反復処理したりしないでください。Avoid indexing the Rows collection or iterating through it with a foreach loop. 通常、行に直接アクセスする必要はありません。You will not typically need to access rows directly. 行を操作する DataGridView メソッドは、行インスタンスではなく行インデックス引数を受け取ります。DataGridView methods that operate on rows take row index arguments rather than row instances. さらに、行関連のイベントのハンドラーは、行プロパティを持つイベント引数オブジェクトを受け取ります。このオブジェクトを使用して、共有を解除することなく行を操作できます。Additionally, handlers for row-related events receive event argument objects with row properties that you can use to manipulate rows without causing them to become unshared.

  • 行オブジェクトにアクセスする必要がある場合は、DataGridViewRowCollection.SharedRow メソッドを使用して、行の実際のインデックスを渡します。If you need to access a row object, use the DataGridViewRowCollection.SharedRow method and pass in the row's actual index. ただし、このメソッドを使用して取得した共有行オブジェクトを変更すると、このオブジェクトを共有するすべての行が変更されることに注意してください。Note, however, that modifying a shared row object retrieved through this method will modify all the rows that share this object. ただし、新しいレコードの行は他の行と共有されないため、他の行を変更しても影響はありません。The row for new records is not shared with other rows, however, so it will not be affected when you modify any other row. また、共有行によって表される異なる行のショートカットメニューが異なる場合もあります。Note also that different rows represented by a shared row may have different shortcut menus. 共有行インスタンスから正しいショートカットメニューを取得するには、GetContextMenuStrip メソッドを使用して、行の実際のインデックスを渡します。To retrieve the correct shortcut menu from a shared row instance, use the GetContextMenuStrip method and pass in the row's actual index. 代わりに、共有行の ContextMenuStrip プロパティにアクセスすると、共有行インデックス-1 が使用され、正しいショートカットメニューは取得されません。If you access the shared row's ContextMenuStrip property instead, it will use the shared row index of -1 and will not retrieve the correct shortcut menu.

  • DataGridViewRow.Cells コレクションのインデックス作成は避けてください。Avoid indexing the DataGridViewRow.Cells collection. セルに直接アクセスすると、親の行が非共有になり、新しい DataGridViewRowがインスタンス化されます。Accessing a cell directly will cause its parent row to become unshared, instantiating a new DataGridViewRow. セル関連イベントのハンドラーは、セルプロパティを使用してイベント引数オブジェクトを受け取ります。このオブジェクトを使用すると、行の共有を解除せずにセルを操作できます。Handlers for cell-related events receive event argument objects with cell properties that you can use to manipulate cells without causing rows to become unshared. また、CurrentCellAddress プロパティを使用して、セルに直接アクセスせずに、現在のセルの行インデックスと列インデックスを取得することもできます。You can also use the CurrentCellAddress property to retrieve the row and column indexes of the current cell without accessing the cell directly.

  • セルベースの選択モードは避けてください。Avoid cell-based selection modes. これらのモードでは、行が共有されなくなります。These modes cause rows to become unshared. 代わりに、DataGridView.SelectionMode プロパティを DataGridViewSelectionMode.FullRowSelect または DataGridViewSelectionMode.FullColumnSelectに設定します。Instead, set the DataGridView.SelectionMode property to DataGridViewSelectionMode.FullRowSelect or DataGridViewSelectionMode.FullColumnSelect.

  • DataGridViewRowCollection.CollectionChanged イベントまたは DataGridView.RowStateChanged イベントは処理しないようにします。Do not handle the DataGridViewRowCollection.CollectionChanged or DataGridView.RowStateChanged events. これらのイベントにより、行が共有されなくなります。These events cause rows to become unshared. また、これらのイベントを発生させる DataGridViewRowCollection.OnCollectionChanged または DataGridView.OnRowStateChanged メソッドを呼び出さないでください。Also, do not call the DataGridViewRowCollection.OnCollectionChanged or DataGridView.OnRowStateChanged methods, which raise these events.

  • DataGridView.SelectionMode プロパティの値が FullColumnSelectColumnHeaderSelectFullRowSelect、または RowHeaderSelectの場合は、DataGridView.SelectedCells コレクションにアクセスしないでください。Do not access the DataGridView.SelectedCells collection when the DataGridView.SelectionMode property value is FullColumnSelect, ColumnHeaderSelect, FullRowSelect, or RowHeaderSelect. これにより、選択したすべての行の共有が解除されます。This causes all selected rows to become unshared.

  • DataGridView.AreAllCellsSelected メソッドを呼び出さないでください。Do not call the DataGridView.AreAllCellsSelected method. このメソッドは、行が共有されなくなる可能性があります。This method can cause rows to become unshared.

  • DataGridView.SelectionMode プロパティ値が CellSelect場合は、DataGridView.SelectAll メソッドを呼び出さないでください。Do not call the DataGridView.SelectAll method when the DataGridView.SelectionMode property value is CellSelect. これにより、すべての行が非共有になります。This causes all rows to become unshared.

  • 列の対応するプロパティが trueに設定されている場合は、セルの ReadOnly または Selected プロパティを false に設定しないでください。Do not set the ReadOnly or Selected property of a cell to false when the corresponding property in its column is set to true. これにより、すべての行が非共有になります。This causes all rows to become unshared.

  • DataGridViewRowCollection.List プロパティにはアクセスしないでください。Do not access the DataGridViewRowCollection.List property. これにより、すべての行が非共有になります。This causes all rows to become unshared.

  • Sort メソッドの Sort(IComparer) オーバーロードは呼び出さないでください。Do not call the Sort(IComparer) overload of the Sort method. カスタム比較子を使用して並べ替えると、すべての行の共有が解除されます。Sorting with a custom comparer causes all rows to become unshared.

参照See also