Ajustar en varias líneas el texto de las celdas en un control DataGridView

Cuando utilizamos un control DataGridView como medio de presentación de los datos de una consulta, si el texto perteneciente a una columna resulta excesivamente largo, el control se ocupa de recortarlo de modo que en las celdas se visualice una parte del mismo, añadiendo al final unos puntos suspensivos, que indican al usuario la existencia de más texto, el cual puede visualizar si redimensiona el ancho de la columna.



Pero supongamos que es conveniente mantener la anchura de las columnas en nuestro control de cuadrícula, siendo necesario que el texto de la mencionada columna pueda ajustarse dentro de la celda, de tal manera que se reparta en varias filas.


Este comportamiento está disponible a través de una de las propiedades de estilo del DataGridView: WrapMode, a la que si asignamos el valor DataGridViewTriState.True, conseguiremos que el texto se divida en la celda sin necesidad de cambiar el ancho de la misma.


Como ejemplo de lo que estamos comentando, el siguiente código fuente carga un DataGridView con los registros de una tabla. Nótese que en la consulta SQL, se crea un campo calculado, concatenando tres de los existentes en la tabla, de forma que consigamos una columna con una buena cantidad de texto, que nos permita realizar las pruebas más adecuadamente.


private void Form1_Load(object sender, EventArgs e)
{
SqlConnection cnConexion = new SqlConnection();
cnConexion.ConnectionString = «Data Source=localhost;» +
«Initial Catalog=Northwind;» +
«Integrated Security=True»;

StringBuilder sbSQL = new StringBuilder();
sbSQL.Append(«SELECT CustomerID, «);
sbSQL.Append(«CompanyName + ‘-‘ + ContactName + ‘-‘ + Address AS DatosCliente, « );
sbSQL.Append(«City, Country FROM Customers»);

SqlCommand cmdComando = new SqlCommand(sbSQL.ToString(), cnConexion);
SqlDataAdapter daAdaptador = new SqlDataAdapter(cmdComando);

DataSet dsDatos = new DataSet();
daAdaptador.Fill(dsDatos, «Customers»);

this.dataGridView1.DataSource = dsDatos;
this.dataGridView1.DataMember = «Customers»;

this.dataGridView1.DefaultCellStyle.BackColor = Color.LightYellow;
this.dataGridView1.DefaultCellStyle.ForeColor = Color.DarkViolet;

// configurar el estilo predeterminado del DataGridView
// para que divida el texto de las celdas en varias líneas
this.dataGridView1.DefaultCellStyle.WrapMode = DataGridViewTriState.True;
}


Sin embargo, el código anterior resuelve el problema sólo en parte, puesto que al ejecutar de nuevo la aplicación, no se muestra el texto de la celda al completo. Podemos observar que en efecto, ahora el texto se ha dividido en varias líneas, pero el usuario debe redimensionar la fila para poder ver el contenido al completo de la celda.



Para conseguir que el DataGridView redimensione automáticamente la altura de sus celdas, adaptándose al contenido de las mismas, es necesario ejecutar el método DataGridView.AutoResizeRows, pasándole como parámetro un valor de la enumeración DataGridViewAutoSizeRowsMode, para establecer el modo de ajuste automático.


Dado que esta operación necesitamos realizarla después de que el control haya terminado de cargar los registros del origen de datos, un lugar adecuado sería el evento Paint del control, como vemos a continuación.


private void dataGridView1_Paint(object sender, PaintEventArgs e)
{
this.dataGridView1.AutoResizeRows(DataGridViewAutoSizeRowsMode.DisplayedCells);
}

Al volver al ejecutar el formulario, las filas del DataGridView adaptarán ahora su altura para mostrar todo el contenido de las celdas sin necesidad de redimensionarlas manualmente.



No obstante, al observar el formulario en ejecución, habremos percibido un efecto de parpadeo, producido por el reajuste continuo que está realizando el control al ejecutar el evento Paint.


Una solución a este problema consistiría en ejecutar el método DataGridView.AutoResizeRows dentro del manipulador del evento Paint solamente una vez, tras la carga inicial de datos del control. Para ello, declararemos una variable con ámbito a nivel de la clase del formulario, que se comporte como un indicador de estado, cambiando su valor tras la primera ejecución de Paint, como vemos en el siguiente bloque de código.


public partial class Form1 : Form
{
// indicador para ajustar la altura de las celdas
// al presentar inicialmente el DataGridView
bool blnAjustarCeldas = true;
//….
private void dataGridView1_Paint(object sender, PaintEventArgs e)
{
if (blnAjustarCeldas)
{
blnAjustarCeldas= false;

this.dataGridView1.AutoResizeRows(DataGridViewAutoSizeRowsMode.DisplayedCells);
}
}
}


Pero todavía no hemos terminado, falta salvar un escollo más, ya que con el ajuste anterior evitamos el efecto de parpadeo, pero al comenzar a desplazarnos por el resto de registros del DataGridView, estas volverán a mostrarse sin el ajuste en su altura. El remedio ahora pasaría por codificar el manipulador del evento Scroll del control, ejecutando también aquí el método DataGridView.AutoResizeRows.


private void dataGridView1_Scroll(object sender, ScrollEventArgs e)
{
this.dataGridView1.AutoResizeRows(DataGridViewAutoSizeRowsMode.DisplayedCells);
}

Tras este último aderezo en nuestro código, ahora sí que funcionará según el objetivo marcado al principio del artículo.


El código fuente puede descargarse en los siguientes enlaces: C# y VB.


Un saludo.


 

21 Comentarios

  1. anonymous

    Muy útil y perfectamente explicado.
    Gracias!

  2. lmblanco

    Hola Rosa

    Muchas gracias por leer el artículo y por tu opinión.

    Un saludo,
    Luismi

  3. anonymous

    Muy bueno tu artículo, m fue de gran ayuda varias de tus lineas utilizadas.

  4. lmblanco

    Hola Juan Carlos

    Gracias por leer el post y celebro que te fuera de utilidad.

    Un saludo,
    Luismi

  5. lmblanco

    Hola Fiorella

    Si necesitas realizar algún tipo de tratamiento de datos en una aplicación desarrollada para .NET Framework, yo te recomendaría que utilizaras ADO.NET, ya que es una tecnología desarrollada para un funcionamiento más óptimo de las operaciones de gestión de datos en este entorno.

    Revisa cualquiera el enlace que tienes en este artículo con el código fuente en VB, para que puedas ver cómo se establece la conexión con la base de datos y se realiza una consulta hacia la misma, también te paso un par de enlaces adicionales sobre ADO.NET, que espero te sean de utilidad.

    http://support.microsoft.com/?scid=kb;es-es;E306636

    http://www.canalvisualbasic.net/temarios/manual_ado.net.asp

    Un saludo,
    Luismi

  6. anonymous

    Muy buen articulo, me ha servido mucho (Y)
    Felicidades!!

  7. lmblanco

    Hola Inductivo

    Gracias por tu interés en el artículo, me alegra que te haya resultado útil.

    Un saludo,
    Luismi

  8. anonymous

    Exelente explicacion aunque estaba en visual c
    lo hice para visual basic y me funciono correctamente mil gracias

  9. lmblanco

    Hola Javier

    Gracias por tu interés en el post. Celebro que te funcionara adaptando el código a vb, aunque al final del texto del post tienes dos enlaces con el proyecto del ejemplo, uno para C# y otro para VB.

    Un saludo,
    Luismi

  10. anonymous

    SUper justo lo q estaba buscando gracias 🙂

  11. lmblanco

    Hola Jas

    Gracias por tu opinión, celebro que te sirviera de ayuda.

    Un saludo,
    Luismi

  12. anonymous

    Gracias por el post! En serio me salvaste. Tenía un problema donde tenía un DataGridView con AutoSizeRowsMode en DisplayedCells, y cuando de repente cambiaba el DataSource del BindingSource que manejaba el grid, ya el resize no servía. No se porque, pero creo que como las celdas todavía no estaban desplegadas, no reajustaba el tamaño. Pero con tu método me funcionó perfectamente!

  13. lmblanco

    Hola Alfonso

    Celebro que mi ejemplo fuera de ayuda 😎

    Un saludo.
    Luismi

  14. anonymous

    Hola, excelente tu aporte alfonso, tenia justo ese problema y nosabia como hacerle me fue de gran ayuda….

  15. anonymous

    JAJAJA 1 hora buscando como mostrar el texto en una fila, la propiedad wrap esta muy escondida en «PROPIEDADES» gracias por el ejemplo

  16. anonymous

    no puedo reajustar las filas…descargue el ejemplo y sigue saliendo en una fila, tengo que redimensionarlo manualmente, ya que no sale de forma automática..:S…alguien puede ayudarme??

  17. lmblanco

    Hola Guillermo

    Gracias por tu interés en el post, y celebro que te haya resultado de ayuda.

    Un saludo,
    Luismi

  18. lmblanco

    Hola Anthony

    He revisado el ejemplo y me funciona correctamente, por favor, revisa por si hay alguna propiedad a la que no has asignado el valor correcto.

    Un saludo,
    Luismi

  19. anonymous

    Gracias por esta ayuda me ha servido de mucho

  20. paul

    hola, tu código funciona bien , pero con mucha data es muy lento incluso se congela la pantalla ¿como podría corregir esto?

    gracias de antemano

Responder a Cancelar respuesta

Tema creado por Anders Norén