Поделиться через


Рекомендации по масштабированию элемента управления DataGridView в Windows Forms

Элемент DataGridView управления предназначен для обеспечения максимальной масштабируемости. Если требуется отобразить большие объемы данных, следует следовать рекомендациям, описанным в этом разделе, чтобы избежать использования большого объема памяти или снижения скорости реагирования пользовательского интерфейса. В этом разделе рассматриваются следующие проблемы:

  • Эффективное использование стилей ячеек

  • Эффективное использование контекстных меню

  • Эффективное использование автоматического изменения размера

  • Эффективное использование выбранных ячеек, строк и коллекций столбцов

  • Использование общих строк

  • Предотвращение отмены состояния общего доступа строк

Если у вас есть особые потребности в производительности, вы можете реализовать виртуальный режим и предоставить собственные операции управления данными. Дополнительные сведения см. в разделе Режимы отображения данных в элементе управления DataGridView Windows Forms.

Эффективное использование стилей ячеек

Каждая ячейка, строка и столбец могут иметь собственные сведения о стиле. Сведения о стиле хранятся в DataGridViewCellStyle объектах. Создание объектов стиля ячеек для многих отдельных DataGridView элементов может быть неэффективным, особенно при работе с большими объемами данных. Чтобы избежать влияния на производительность, используйте следующие рекомендации.

Эффективное использование контекстных меню

Каждая ячейка, строка и столбец могут иметь собственное контекстное меню. Контекстные меню в DataGridView элементах управления представлены через ContextMenuStrip элементы управления. Как и в случае с объектами стиля ячеек, создание контекстных меню для многих отдельных DataGridView элементов негативно влияет на производительность. Чтобы избежать этого наказания, используйте следующие рекомендации:

  • Избегайте создания контекстных меню для отдельных ячеек и строк. К ним относится шаблон строки, который клонируется вместе с контекстным меню при добавлении новых строк в элемент управления. Для максимальной масштабируемости используйте только свойство элемента управления ContextMenuStrip , чтобы указать одно контекстное меню для всего элемента управления.

  • Если вам нужно несколько контекстных меню для нескольких строк или ячеек, обработайте события CellContextMenuStripNeeded или RowContextMenuStripNeeded. Эти события позволяют самостоятельно управлять объектами контекстного меню, позволяя настраивать производительность.

Эффективно использовать автоматическое изменение размера

Строки, столбцы и заголовки могут автоматически изменять размер по мере изменения содержимого ячеек, чтобы все содержимое ячеек отображалось без обрезки. Изменение режимов изменения размера также может изменять размер строк, столбцов и заголовков. Чтобы определить правильный размер, DataGridView элемент управления должен проверить значение каждой ячейки, которую он должен разместить. При работе с большими наборами данных этот анализ может отрицательно сказаться на производительности элемента управления при автоматическом изменении его размера. Чтобы избежать штрафов за производительность, используйте следующие рекомендации.

  • Избегайте автоматического изменения размера элемента управления DataGridView, если имеется большой набор строк. Если вы используете автоматическое изменение размера, измените размер только на основе отображаемых строк. Используйте только отображаемые строки в виртуальном режиме.

  • Для максимальной масштабируемости отключите автоматическое изменение размера и используйте программный размер.

Дополнительные сведения см. в разделе Настройки размера в элементе управления Windows Forms DataGridView.

Эффективное использование выбранных ячеек, строк и коллекций столбцов

Коллекция SelectedCells не работает эффективно с большими выборками. Коллекции SelectedRows и SelectedColumns также могут быть неэффективными, хотя и в меньшей степени, поскольку в типичном элементе управления DataGridView гораздо меньше строк, чем ячеек, и гораздо меньше столбцов, чем строк. Чтобы избежать штрафов за производительность при работе с этими коллекциями, используйте следующие рекомендации:

Использование общих строк

Эффективное использование памяти достигается в DataGridView контроле с помощью общих строк. Строки будут делиться максимальной информацией о их внешнем виде и поведении, предоставляя общий доступ к экземплярам DataGridViewRow класса.

Хотя общий доступ к экземплярам строк экономит память, строки могут легко утратить общий доступ. Например, каждый раз, когда пользователь взаимодействует непосредственно с ячейкой, строка перестает быть общей. Так как это не удается избежать, рекомендации в этом разделе полезны только при работе с очень большими объемами данных, и только если пользователи будут взаимодействовать с относительно небольшой частью данных при каждом запуске программы.

Строка не может быть разделена в элементе управления без привязки DataGridView, если в какой-либо из его ячеек содержатся значения. DataGridView Если элемент управления привязан к внешнему источнику данных или при реализации виртуального режима и использовании собственного источника данных, значения ячеек хранятся вне элемента управления, а не в объектах ячеек, что позволяет строкам быть общими.

Объект строки можно использовать только в том случае, если состояние всех его ячеек можно определить из состояния строки и состояний столбцов, содержащих ячейки. Если изменить состояние ячейки таким образом, чтобы оно больше не выводилось из состояния ее строки и столбца, строку нельзя будет использовать совместно.

Например, строку нельзя совместно использовать в любой из следующих ситуаций:

  • Строка содержит одну выбранную ячейку, которая не находится в выбранном столбце.

  • Строка содержит ячейку с установленными свойствами ToolTipText или ContextMenuStrip.

  • Строка содержит DataGridViewComboBoxCell, у которого установлено свойство Items.

В связанном или виртуальном режиме можно предоставлять подсказки и меню быстрого доступа для отдельных ячеек, обрабатывая события CellToolTipTextNeeded и CellContextMenuStripNeeded.

Элемент DataGridView управления автоматически пытается использовать общие строки всякий раз, когда строки добавляются в DataGridViewRowCollection. Используйте следующие инструкции, чтобы обеспечить совместное использование строк:

  • Избегайте вызова Add(Object[]) перегрузки Add метода и Insert(Object[]) перегрузки Insert метода DataGridView.Rows коллекции. Эти перегрузки автоматически создают неделимые строки.

  • Убедитесь, что строка, указанная в свойстве DataGridView.RowTemplate , может использоваться в следующих случаях:

  • Убедитесь, что строка, указанная параметром indexSource, может быть использована при вызове методов AddCopy, AddCopies, InsertCopy и InsertCopies коллекции DataGridView.Rows.

  • Убедитесь, что указанные строки или строки можно совместно использовать при вызове перегрузки Add(DataGridViewRow) метода Add, метода AddRange, перегрузки Insert(Int32,DataGridViewRow) метода Insert и метода InsertRange коллекции DataGridView.Rows.

Чтобы определить, является ли строка общей, используйте DataGridViewRowCollection.SharedRow метод для извлечения объекта строки, а затем проверьте свойство объекта 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.SelectedCells коллекции, если значение свойства DataGridView.SelectionMode равно FullColumnSelect, ColumnHeaderSelect, FullRowSelect или RowHeaderSelect. Это приводит к тому, что все выбранные строки перестают быть общими.

  • Не вызывайте DataGridView.AreAllCellsSelected метод. Этот метод может привести к тому, что строки перестанут быть общими.

  • Не вызывайте DataGridView.SelectAll метод, если DataGridView.SelectionMode значение свойства равно CellSelect. Это приводит к тому, что все строки становятся разделенными.

  • Не устанавливайте свойство ReadOnly или Selected ячейки на false, если соответствующее свойство столбца установлено на true. Это приводит к тому, что все строки становятся разделенными.

  • Не обращаться к свойству DataGridViewRowCollection.List . Это приводит к тому, что все строки становятся разделенными.

  • Не вызывайте перегруженный метод Sort(IComparer)Sort. Сортировка с помощью настраиваемого средства сравнения приводит к тому, что все строки становятся неразделяемыми.

См. также