Procedimientos recomendados para ajustar la escala del control DataGridView en formularios Windows Forms
Actualización: noviembre 2007
Se ha diseñado el control DataGridView para proporcionar la escalabilidad máxima. Si tiene que mostrar grandes cantidades de datos, siga las instrucciones descritas en este tema para impedir la utilización de grandes cantidades de memoria o la disminución de la capacidad de respuesta de la interfaz de usuario (IU). En este tema se tratan los siguientes materias:
Utilizar estilos de celda eficazmente
Utilizar menús contextuales eficazmente
Utilizar el cambio de tamaño automático eficazmente
Utilizar las celdas, filas y colecciones de columnas seleccionadas eficazmente
Utilizar filas compartidas
Impedir que las filas dejen de estar compartidas
Si tiene necesidades de rendimiento especiales, puede implementar el modo virtual y proporcionar sus propias operaciones de administración de datos. Para obtener más información, vea Modos de presentación de datos en el control DataGridView de formularios Windows Forms.
Utilizar estilos de celda eficazmente
Cada celda, fila y columna puede tener su propia información de estilo. La información de estilo se almacena en objetos DataGridViewCellStyle. Crear objetos de estilo de celda para muchos elementos DataGridView individuales pueden resultar ineficaz, sobre todo al trabajar con grandes cantidades de datos. Para evitar un impacto en el rendimiento, utilice las instrucciones siguientes:
Evite configurar propiedades de estilo de celda para objetos DataGridViewCell o DataGridViewRow individuales. Esto incluye el objeto de fila especificado por la propiedad RowTemplate. Cada nueva fila que se clona de la plantilla de fila recibirá su propia copia del objeto de estilo de celda de la plantilla. Para obtener una escalabilidad máxima, establezca las propiedades de estilo de celda en el nivel DataGridView. Por ejemplo, establezca la propiedad DataGridView.DefaultCellStyle en lugar de la propiedad DataGridViewCell.Style.
Si algunas celdas requieren un formato distinto del predeterminado, utilice las mismas instancias de DataGridViewCellStyle entre grupos de celdas, filas o columnas. Evite establecer directamente propiedades de tipo DataGridViewCellStyle en celdas, filas y columnas individuales. Para obtener un ejemplo de cómo se comparten estilos de celda, vea Cómo: Establecer estilos de celda predeterminados para el control DataGridView de formularios Windows Forms. Para impedir también una reducción del rendimiento al establecer estilos de celda de manera individual utilice el controlador de eventos CellFormatting. Para obtener un ejemplo, vea Cómo: Personalizar el formato de los datos en el control DataGridView de formularios Windows Forms.
Al determinar un estilo de celda, utilice la propiedad DataGridViewCell.InheritedStyle en lugar de la propiedad DataGridViewCell.Style. Al tener acceso a la propiedad Style, se crea una nueva instancia de la clase DataGridViewCellStyle si aún no se ha utilizado la propiedad. Además, este objeto quizá no contenga la información de estilo completa para la celda si algunos estilos se heredan de la fila, columna o control. Para obtener más información sobre herencia de estilos de celda, vea Estilos de celda en el control DataGridView de formularios Windows Forms.
Utilizar los menús contextuales eficazmente
Cada celda, fila y columna puede tener su propio menú contextual. Los controles ContextMenuStrip representan los menús contextuales del control DataGridView. Igual que con objetos de estilo de celda, al crear menús contextuales para gran cantidad de elementos DataGridView individuales reducirá el rendimiento. Para impedir esta situación, utilice las instrucciones siguientes:
Evite crear menús contextuales para celdas y filas individuales. Esto incluye la plantilla de fila, que se clona junto con su menú contextual cuando se agregan nuevas filas al control. Para obtener una escalabilidad máxima, utilice sólo la propiedad ContextMenuStrip del control para especificar un solo menú contextual para el control completo.
Si requiere varios menús contextuales para varias filas o celdas, controle los eventos CellContextMenuStripNeeded o RowContextMenuStripNeeded. Estos eventos permiten que administre objetos de menú contextual, lo que le permite ajustar el rendimiento.
Utilizar el cambio de tamaño automático eficazmente
Se puede cambiar automáticamente el tamaño de filas, columnas y encabezados a medida que el contenido de la celda cambia de modo que el contenido completo de las celdas se muestre sin recortar. Al cambiar los modos de ajuste de tamaño también se puede cambiar el tamaño de filas, columnas y encabezados. Para determinar el tamaño correcto, el control DataGridView debe examinar el valor de todas las celdas que debe alojar. Al trabajar con grandes conjuntos de datos, este análisis puede impactar en el rendimiento del control cuando se produce el cambio de tamaño automático. Para impedir la reducción del rendimiento, utilice las instrucciones siguientes:
Evite utilizar el tamaño automático en un control DataGridView con un conjunto de gran volumen de filas. Si utiliza el tamaño automático, sólo cambie el tamaño basándose en las filas mostradas. Utilice sólo las filas mostradas en modo virtual también.
Para filas y columnas, utilice el campo DisplayedCells o DisplayedCellsExceptHeaders de las enumeraciones DataGridViewAutoSizeRowsMode, DataGridViewAutoSizeColumnsMode y DataGridViewAutoSizeColumnMode.
Para los encabezados de fila, utilice el campo AutoSizeToDisplayedHeaders o AutoSizeToFirstHeader de la enumeración DataGridViewRowHeadersWidthSizeMode.
Para obtener la escalabilidad máxima, desactive el tamaño automático y utilice el cambio de tamaño mediante programación.
Para obtener más información, vea Opciones de ajuste de tamaño en el control DataGridView de formularios Windows Forms.
Utilizar eficazmente las celdas, filas y las colecciones de columnas seleccionadas
La colección SelectedCells no se ejecuta eficazmente con grandes selecciones. Las colecciones SelectedRows y SelectedColumns también pueden resultar ineficaces, aunque con un grado menor porque hay muchas menos filas que celdas en un control DataGridView corriente y muchas menos columnas que filas. Para evitar las reducciones del rendimiento al trabajar con estas colecciones, utilice las instrucciones siguientes:
Para determinar si se han seleccionado todas las celdas del DataGridView antes de tener acceso al contenido de la colección SelectedCells, compruebe el valor devuelto del método AreAllCellsSelected. Observe, sin embargo, que este método puede producir que las filas dejen de ser compartidas. Para obtener más información, vea la siguiente sección.
Evite utilizar la propiedad Count de System.Windows.Forms.DataGridViewSelectedCellCollection para determinar el número de celdas seleccionadas. En su lugar, utilice el método DataGridView.GetCellCount y pase el valor DataGridViewElementStates.Selected. De igual forma, utilice los métodos DataGridViewRowCollection.GetRowCount y DataGridViewColumnCollection.GetColumnCount para determinar el número de elementos seleccionados, en lugar de tener acceso a la fila y las colecciones de columnas seleccionadas.
Evite los modos de selección basados en celdas. En su lugar, puede establecer también la propiedad DataGridView.SelectionMode en DataGridViewSelectionMode.FullRowSelect o DataGridViewSelectionMode.FullColumnSelect.
Utilizar filas compartidas
El uso eficaz de la memoria se consigue en el control DataGridView a través de filas compartidas. Las filas compartirán toda la información que sea posible sobre su apariencia y comportamiento compartiendo instancias de la clase DataGridViewRow.
Aunque compartir instancias de fila ahorra memoria, las filas pueden dejar de estar compartidas fácilmente. Por ejemplo, cada vez que un usuario interactúa directamente con una celda, su fila deja de estar compartida. Dado que no se puede evitar esto, las instrucciones de este tema resultan de utilidad sólo cuando se trabaja con grandes cantidades de datos y sólo cuando los usuarios interactuarán con un parte de los datos relativamente pequeña cada vez que se ejecuta el programa.
Una fila no se puede compartir en un control DataGridView independiente si cualquiera de sus celdas contiene valores. Cuando el control DataGridView está enlazado a un origen de datos externo o cuando implementa el modo virtual y proporciona su propio origen de datos, los valores de celda se almacenan fuera del control en lugar de en otros objetos, lo que permite compartir filas.
Un objeto de fila sólo se puede compartir si el estado de todas sus celdas se puede determinar del estado de la fila y de los estados de las columnas que contienen las celdas. Si cambia el estado de una celda de modo que ya no se puede deducir el estado de su fila y columna, no se podrá compartir la fila.
Por ejemplo, una fila no se puede compartir en cualquiera de las situaciones siguientes:
La fila contiene una celda seleccionada única que no está en una columna seleccionada.
La fila contiene una celda con sus propiedades ToolTipText o ContextMenuStrip establecidas.
La fila contiene DataGridViewComboBoxCell con su propiedad Items establecida.
En el modo de enlace o el modo virtual, puede proporcionar información sobre herramientas y menús contextuales para celdas individuales controlando los eventos CellToolTipTextNeeded y CellContextMenuStripNeeded.
El control DataGridView intentará utilizar automáticamente filas compartidas cada vez que se agreguen filas a DataGridViewRowCollection. Utilice las instrucciones siguientes para garantizar que se comparten las filas:
Evite llamar a la sobrecarga Add(Object[]) del método Add y la sobrecarga Insert(Object[]) del método Insert de la colección DataGridView.Rows. Estas sobrecargas crean automáticamente filas no compartidas.
Asegúrese de que la fila especificada en la propiedad DataGridView.RowTemplate se puede compartir en los casos siguientes:
Al llamar a las sobrecargas Add() o Add(Int32) del método Add o la sobrecarga Insert(Int32,Int32) del método Insert de la colección DataGridView.Rows.
Al aumentar el valor de la propiedad DataGridView.RowCount.
Al establecer la propiedad DataGridView.DataSource.
Asegúrese de que la fila indicada por el parámetro indexSource se puede compartir al llamar a los métodos: AddCopy, AddCopies, InsertCopy y InsertCopies de la colección DataGridView.Rows.
Asegúrese de que se puede compartir la fila o filas especificadas cuando se llama a la sobrecarga Add(DataGridViewRow) del método Add, al método AddRange, al método Insert(Int32,DataGridViewRow), al método Insert y al método InsertRange de la colección DataGridView.Rows.
Para determinar si se comparte una fila, utilice el método DataGridViewRowCollection.SharedRow para recuperar el objeto de fila y, a continuación, compruebe la propiedad Index del objeto. Las filas compartidas siempre tienen un valor de la propiedad Index de -1.
Impedir que las filas dejen de estar compartidas
Las filas compartidas pueden dejar de estar compartidas como consecuencia del código o de la acción del usuario. Para impedir un impacto en el rendimiento, evite provocar que las filas dejen de estar compartidas. Durante el desarrollo de aplicaciones, puede controlar el evento RowUnshared para determinar cuándo dejan de estar compartidas las filas. Esto resulta de utilidad al depurar problemas de uso compartido de filas.
Para impedir que las filas dejen de estar compartidas, utilice las instrucciones siguientes:
Evite la indización de la colección Rows o el recorrido en iteración por ésta con un bucle foreach. Normalmente no necesitará obtener acceso a las filas directamente. Los métodos DataGridView que operan en filas toman argumentos de índice de fila en lugar de instancias de fila. De forma adicional, los controladores de eventos relacionados con filas reciben objetos de argumento de evento con propiedades de fila que puede utilizar para manipular filas sin producir que éstas dejen de estar compartidas.
Si necesita tener acceso a un objeto de fila, utilice el método DataGridViewRowCollection.SharedRow y pase el índice real de la fila. Observe, sin embargo, que al modificar un objeto de fila compartido recuperado a través de este método, se modificarán todas las filas que comparten este objeto. La fila para los nuevos registros no se comparte con otras filas, sin embargo, esto no se verá afectado cuando modifique cualquier otra fila. También tenga en cuenta que filas distintas representadas por una fila compartida pueden tener menús contextuales distintos. Para recuperar el menú contextual correcto de una instancia de fila compartida, utilice el método GetContextMenuStrip y pase el índice real de la fila. Si en su lugar tiene acceso a la propiedad ContextMenuStrip de la fila compartida, se utilizará el índice de fila compartida de -1 y no se recuperará el menú contextual correcto.
Evite la indización de la colección DataGridViewRow.Cells. Al tener acceso directamente a una celda, se producirá que su fila primaria deje de estar compartida, que crea una instancia de un nuevo DataGridViewRow. Los controladores para los eventos relacionados con celda reciben los objetos de argumento de evento con propiedades de celda que puede utilizar para manipular las celdas sin provocar que las filas dejen de estar compartidas. También puede utilizar la propiedad CurrentCellAddress para recuperar los índices de fila y columna de la celda actual sin tener acceso directamente a la celda.
Evite los modos de selección basados en celdas. Estos modos producen que las filas dejen de estar compartidas. En su lugar, puede establecer también la propiedad DataGridView.SelectionMode en DataGridViewSelectionMode.FullRowSelect o DataGridViewSelectionMode.FullColumnSelect.
No controle los eventos DataGridViewRowCollection.CollectionChanged o DataGridView.RowStateChanged. Estos eventos hacen que las filas dejen de estar compartidas. Además, no llame a los métodos DataGridViewRowCollection.OnCollectionChanged o DataGridView.OnRowStateChanged, que provocan estos eventos.
No obtenga acceso a la colección DataGridView.SelectedCells cuando el valor de la propiedad DataGridView.SelectionMode sea FullColumnSelect, ColumnHeaderSelect, FullRowSelect o RowHeaderSelect. Esto hace que las filas seleccionadas dejen de estar compartidas.
No llame al método DataGridView.AreAllCellsSelected. Este método puede provocar que las filas dejen de estar compartidas.
No llame al método DataGridView.SelectAll cuando el valor de la propiedad DataGridView.SelectionMode sea CellSelect. Esto hace que todas las filas dejen de estar compartidas.
No establezca la propiedad ReadOnly o Selected de una celda en false cuando la propiedad correspondiente de su columna esté establecida en true. Esto hace que todas las filas dejen de estar compartidas.
No obtenga acceso a la propiedad DataGridViewRowCollection.List. Esto hace que todas las filas dejen de estar compartidas.
No llame a la sobrecarga Sort(IComparer) del método Sort. Al realizar la ordenación con un comparador personalizado se produce que todas las filas dejen de estar compartidas.
Vea también
Tareas
Conceptos
Modo virtual del control DataGridView de formularios Windows Forms
Modos de presentación de datos en el control DataGridView de formularios Windows Forms
Estilos de celda en el control DataGridView de formularios Windows Forms
Opciones de ajuste de tamaño en el control DataGridView de formularios Windows Forms
Referencia
Otros recursos
Ajuste del rendimiento del control DataGridView en formularios Windows Forms