Procedimientos recomendados para ajustar la escala del control DataGridView en formularios Windows Forms

El control DataGridView está diseñado para proporcionar la máxima escalabilidad. Si necesita mostrar grandes cantidades de datos, debe seguir las indicaciones que se describen en este tema para evitar consumir grandes cantidades de memoria o degradar la capacidad de respuesta de la interfaz de usuario. En este tema se tratan las cuestiones siguientes:

  • Uso eficaz de los estilos de celda

  • Uso eficaz de los menús contextuales

  • Uso eficaz del cambio de tamaño automático

  • Uso eficaz de las colecciones de celdas, filas y columnas seleccionadas

  • Uso de filas compartidas

  • Prevención de 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, consulte Modos de presentación de datos en el control DataGridView de Windows Forms.

Uso eficaz de los estilos de celda

Cada celda, fila y columna puede tener su propia información de estilo. La información de estilo se almacena en objetos DataGridViewCellStyle. La creación de objetos de estilo de celda para muchos elementos DataGridView individuales puede ser ineficaz, sobre todo cuando se trabaja con grandes cantidades de datos. Para evitar un impacto en el rendimiento, siga estas indicaciones:

Uso eficaz de los menús contextuales

Cada celda, fila y columna puede tener su propio menú contextual. Los menús contextuales del control DataGridView se representan mediante controles ContextMenuStrip. Al igual que sucede con los objetos de estilo de celda, la creación de menús contextuales para muchos elementos DataGridView individuales afectará negativamente al rendimiento. Para evitar que el rendimiento disminuya, siga estas indicaciones:

  • Evite crear menús contextuales para celdas y filas individuales. Esto incluye la plantilla de fila, que se clona con su menú contextual cuando se agregan nuevas filas al control. Para obtener la máxima escalabilidad, use solo la propiedad ContextMenuStrip del control para especificar un solo menú contextual para todo el control.

  • Si necesita varios menús contextuales para varias filas o celdas, controle los eventos CellContextMenuStripNeeded o RowContextMenuStripNeeded. Con estos eventos podrá administrar por su cuenta los objetos de menú contextual, lo que le permitirá optimizar el rendimiento.

Uso eficaz del cambio de tamaño automático

El tamaño de las filas, columnas y encabezados se puede cambiar automáticamente cuando el contenido de las celdas cambia, de modo que todo el contenido de las celdas se muestre sin recortar. Al modificar los modos de dimensionamiento también puede cambiar el tamaño de las filas, columnas y encabezados. Para determinar el tamaño correcto, el control DataGridView debe examinar el valor de cada celda que debe alojar. Al trabajar con grandes conjuntos de datos, este análisis puede afectar negativamente al rendimiento del control cuando se produce un cambio de tamaño automático. Para evitar una disminución del rendimiento, siga estas indicaciones:

Para obtener más información, vea Opciones de dimensionamiento en el control DataGridView de Windows Forms.

Uso eficaz de las colecciones de celdas, filas y columnas seleccionadas

La colección SelectedCells no funciona de forma eficaz con selecciones grandes. Las colecciones SelectedRows y SelectedColumns también pueden ser ineficaces, aunque en menor medida porque hay muchas menos filas que celdas en un control DataGridView típico, y muchas menos columnas que filas. Para evitar una disminución del rendimiento al trabajar con estas colecciones, siga estas indicaciones:

Uso de filas compartidas

Se consigue un uso eficaz de la memoria en el control DataGridView mediante las filas compartidas. Las filas compartirán tanta información sobre su apariencia y su comportamiento como sea posible al compartir instancias de la clase DataGridViewRow.

Aunque el uso compartido de instancias de fila ahorra memoria, las filas pueden dejar de compartirse fácilmente. Por ejemplo, cada vez que un usuario interactúa directamente con una celda, su fila deja de compartirse. Dado que esto no se puede evitar, las indicaciones de este tema solo son útiles cuando se trabaja con grandes cantidades de datos y cuando los usuarios interactúan con una parte relativamente pequeña de los datos cada vez que se ejecuta el programa.

No se puede compartir una fila en un control DataGridView sin enlazar si alguna 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 objetos de celda, lo que permite compartir las filas.

Un objeto de fila solo se puede compartir si el estado de todas sus celdas se puede determinar a partir del estado de la fila y los estados de las columnas que contienen las celdas. Si cambia el estado de una celda para que ya no se pueda deducir a partir del estado de su fila y columna, la fila no se puede compartir.

Por ejemplo, una fila no se puede compartir en ninguna de las situaciones siguientes:

En el modo enlazado o el modo virtual, puede proporcionar información sobre herramientas y menús contextuales para celdas individuales si controla los eventos CellToolTipTextNeeded y CellContextMenuStripNeeded.

El control DataGridView intentará usar automáticamente filas compartidas cada vez que se agreguen filas a DataGridViewRowCollection. Siga estas indicaciones para asegurarse de que las filas se comparten:

Para determinar si una fila es compartida, use el método DataGridViewRowCollection.SharedRow para recuperar el objeto de fila y, luego, compruebe la propiedad Index del objeto. Las filas compartidas siempre tienen un valor de propiedad Index de –1.

Prevención de que las filas dejen de estar compartidas

Las filas compartidas pueden dejar de compartirse como resultado del código o de una acción del usuario. Para evitar que afecte al rendimiento, debe evitar que las filas dejen de compartirse. Durante el desarrollo de la aplicación, puede controlar el evento RowUnshared para determinar si las filas dejan de compartirse. Esto resulta útil al depurar problemas relacionados con el uso compartido de filas.

Para evitar que las filas dejen de compartirse, siga estas indicaciones:

  • Evite indexar la colección Rows o iterarla con un bucle foreach. Normalmente, no necesitará acceder a las filas directamente. Los métodos DataGridView que operan en filas toman argumentos de índice de fila, en lugar de instancias de fila. Además, los controladores de eventos relacionados con filas reciben objetos de argumento de evento con propiedades de fila que se pueden usar para manipular filas sin que dejen de compartirse.

  • Si necesita acceder a un objeto de fila, use el método DataGridViewRowCollection.SharedRow y pase el índice real de la fila. Aun así, tenga en cuenta que, si se modifica un objeto de fila compartida recuperado mediante este método, se modificarán todas las filas que comparten este objeto. La fila de los nuevos registros no se comparte con otras filas, por lo que no se verá afectada si se modifica otra fila. Tenga en cuenta también que diferentes filas representadas por una fila compartida pueden tener menús contextuales diferentes. Para recuperar el menú contextual correcto de una instancia de fila compartida, use el método GetContextMenuStrip y pase el índice real de la fila. Si accede a la propiedad ContextMenuStrip de la fila compartida, usará el índice de fila compartida de -1 y no recuperará el menú contextual correcto.

  • Evite indexar la colección DataGridViewRow.Cells. Al acceder a una celda directamente, su fila primaria dejará de compartirse y se creará una instancia de un nuevo objeto DataGridViewRow. Los controladores de eventos relacionados con celdas reciben objetos de argumento de evento con propiedades de celda que se pueden usar para manipular celdas sin que las filas dejen de compartirse. También puede usar la propiedad CurrentCellAddress para recuperar los índices de fila y columna de la celda actual sin acceder a la celda directamente.

  • Evite los modos de selección basados en celdas. Estos modos hacen que las filas dejen de compartirse. En su lugar, establezca 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 compartirse. Además, no llame a los métodos DataGridViewRowCollection.OnCollectionChanged o DataGridView.OnRowStateChanged, que generan estos eventos.

  • No acceda a la colección DataGridView.SelectedCells cuando el valor de la propiedad DataGridView.SelectionMode sea FullColumnSelect, ColumnHeaderSelect, FullRowSelect o RowHeaderSelect. Esto hace que todas las filas seleccionadas dejen de compartirse.

  • No llame al método DataGridView.AreAllCellsSelected. Este método puede hacer que las filas dejen de compartirse.

  • 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 compartirse.

  • 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 compartirse.

  • No acceda a la propiedad DataGridViewRowCollection.List. Esto hace que todas las filas dejen de compartirse.

  • No llame a la sobrecarga Sort(IComparer) del método Sort. La ordenación con un comparador personalizado hace que todas las filas dejen de compartirse.

Consulte también