Eliminar los bordes de separación de celdas en el control DataGridView

Entre las características predeterminadas del control DataGridView de Windows Forms, se encuentra la visualización de las líneas de separación que delimitan las celdas que componen la cuadrícula de datos.


Si por alguna circunstancia no deseamos que dichas líneas se muestren al usuario, podemos utilizar la propiedad CellBorderStyle, asignándole el valor None de la enumeración DataGridViewCellBorderStyle, la cual nos permite también aplicar diversos efectos de resaltado de estas líneas.


this.dataGridView1.CellBorderStyle = DataGridViewCellBorderStyle.None;

La siguiente imagen muestra el control después de haber ocultado sus líneas.



Pero siendo un poco más rebuscados, supongamos que queremos eliminar estas líneas de una forma selectiva, por ejemplo, la línea vertical que separa las dos primeras columnas. En este caso, la propiedad CellBorderStyle no resulta de ayuda, por lo que tendremos que recurrir a una técnica un poco más compleja, basada en realizar el dibujo de todos los elementos de la celda manualmente mediante el evento CellPainting del DataGridView.


Como podemos adivinar por su nombre, CellPainting es un evento que se desencadenará cada vez que el control necesite pintar una celda, por lo que resulta el punto idóneo para personalizar el modo en cómo queremos que se muestre el dato contenido en la celda al usuario.


El procedimiento a seguir para realizar el dibujo personalizado de una celda consiste en comprobar en primer lugar si estamos ante la fila y columna que necesitamos. A continuación también observaremos si la celda está seleccionada, ya que en ese caso tendremos que utilizar una combinación de colores distinta para resaltar el contenido.


Seguidamente dibujamos el rectángulo correspondiente a la celda, cuyas dimensiones obtenemos de la propiedad CellBounds, perteneciente al parámetro DataGridViewCellPaintingEventArgs que recibe este evento, rellenándolo con el color de fondo que corresponda: seleccionado o normal. Para que la combinación de colores se ajuste a la utilizada por los controles estándar, emplearemos los colores obtenidos a partir de las propiedades públicas pertenecientes a la clase SystemColors.


En el siguiente paso dibujaremos únicamente la línea vertical de separación para las filas de la celda.  En el caso de que la celda tenga un valor que mostrar, lo dibujaremos mediante el método estático DrawText de la clase TextRenderer, pasando, entre otros valores, el tipo de letra que obtenemos del estilo correspondiente a la celda, el rectángulo sobre el que se dibujará el texto que nos proporciona el parámetro DataGridViewCellPaintingEventArgs. CellBounds, y el color que hemos establecido anteriormente tras comprobar si la celda estaba o no seleccionada.


Dado que estamos pintando de modo personalizado la celda, terminaremos el código del manipulador de este evento indicando dicha circunstancia -asignando el valor true a la propiedad DataGridViewCellPaintingEventArgs.Handled-,  para así evitar que el control intente realizar alguna acción de dibujo sobre la celda por su cuenta. El código fuente necesario podemos verlo a continuación.


private void dataGridView1_CellPainting(object sender, DataGridViewCellPaintingEventArgs e)
{
// comprobar que la fila y columna son las adecuadas
if (e.RowIndex >= 0 && (e.ColumnIndex == 0))
{
Color clrFondoCelda;
Color clrTextoCelda;
// en función de si la celda está o no seleccionada
// establecer los colores
if ((e.State & DataGridViewElementStates.Selected) == DataGridViewElementStates.Selected)
{
clrFondoCelda = SystemColors.Highlight;
clrTextoCelda = SystemColors.Window;
}
else
{
clrFondoCelda = SystemColors.Window;
clrTextoCelda = SystemColors.WindowText;
}

// rellenar el rectángulo de la celda con el color correspondiente
e.Graphics.FillRectangle(new SolidBrush(clrFondoCelda), e.CellBounds);

// dibujar solamente la línea vertical de la celda
e.Graphics.DrawLine(new Pen(SystemColors.ActiveBorder),
new Point(e.CellBounds.X, e.CellBounds.Y + e.CellBounds.Height – 1),
new Point(e.CellBounds.X + e.CellBounds.Width, e.CellBounds.Y + e.CellBounds.Height – 1));

// si la celda tiene valor
if (e.Value != null)
{
// dibujar el texto
TextRenderer.DrawText(e.Graphics,
e.FormattedValue.ToString(),
e.CellStyle.Font,
e.CellBounds,
clrTextoCelda);
}

e.Handled = true;
}
}


El efecto de la eliminación de esta línea en las celdas podemos apreciarlo en la siguiente imagen.



Observemos un efecto curioso: el texto de la celda que hemos dibujado mediante CellPainting ha quedado alineado en el centro, cuando por defecto queda a la izquierda. Si queremos que dicha alineación permanezca en el lugar original, hemos de añadir un parámetro adicional al método TextRenderer.DrawText. Dicho parámetro es un valor de la enumeración TextFormatFlags, que nos permite aplicar este y otro tipo de efectos al texto que dibujemos manualmente.


TextRenderer.DrawText(e.Graphics,
e.FormattedValue.ToString(),
e.CellStyle.Font,
e.CellBounds,
clrTextoCelda,
TextFormatFlags.Left);

Ahora las celdas de esta columna ya se mostrarán con la alineación correcta.



El código fuente de este ejemplo puede descargarse en estos enlaces para C# y VB.


Un saludo.

7 Comentarios

  1. johnnynet20

    hola luis, me llamo johnny soy de [Lima-Peru] sabes siempre leo tus articulos, los cuales me parecen muy interesantes y tecnicos sobre todo entendibles, tambien he notado que posteas sobre aplicaciones de escritorio lo cual me fascina gracias por los articulos y feliz dia de la amistad a todos los Geeks…!!

    Johnny Quispe.. 😀

  2. lmblanco

    Hola Johnny

    Pues te agradezco profundamente que te intereses por los artículos que publico y celebro que te resulten de interés y utilidad.

    Aunque actualmente me interesa mucho todas las apasionantes tecnologías que están emergiendo: WPF, Silverlight, AJAX, etc., he pasado mucho tiempo desarrollando aplicaciones de escritorio, y siempre ocuparán un lugar en mi corazoncito 8-).

    Muchas gracias por leer los posts del blog.

    Un saludo y encantado de conocerte 8-D
    Luismi

  3. lmblanco

    Hola Enrique

    Muchas gracias por leer el post, me alegro que te haya gustado y espero que te pueda servir de utilidad en algún momento 😎

    Un saludo,
    Luismi

  4. anonymous

    Necesito poder unir celdas de un DataGridView, algo como lo que podemos hacer en un exel, que me permita las celdas de dos o mas columnas o filas. Gracias de antemano

  5. lmblanco

    Hola Harold

    Puedes probar a emplear un truco consistente en preparar tu consulta SQL con un campo calculado que contenga las columnas unidas.

    Si tienes una consulta como la siguiente para tu datagridview, donde inicialmente no unes columnas.

    SELECT Campo1, Campo2, Campo3 FROM Tabla

    En el momento en que tengas que realizar la unión, puedes volver a ejecutar la consulta para repoblar el datagridview usando una consulta como la siguiente

    SELECT Campo1, Campo2 + Campo3 AS CampoNuevo FROM Tabla

    Un saludo,
    Luismi

  6. anonymous

    El aporte está excelente, pero me interesa saber cómo puedo combinar celda en el datagridview; similar a la forma en que se hace en excel. Si sabes como hacer eso, le agradezco de antemano su ayuda.

    Trabajo desarrollando software por cuenta propia, y necesito aplicar esto en un programa que estoy elaborando.
    Gracias.

  7. lmblanco

    Hola Manuel

    Gracias por tu interés. Respecto a tu comentario, te paso un enlace en el que se comenta una propuesta para conseguir la funcionalidad que mencionas.

    http://www.codeguru.com/forum/archive/index.php/t-415930.html

    Un saludo,
    Luismi

Responder a Cancelar respuesta

Tema creado por Anders Norén