Formatear y resaltar valores en el control DataGridView con el evento CellFormatting (y III)
Como colofón a esta serie de artículos, en esta entrega explicamos el modo de aplicar formatos a las columnas del DataGridView en función del tipo de su dato, mediante expresiones reguladas y sobre filas completas del control.
Aplicar un estilo como formato según el tipo de dato
En caso de que en un mismo proceso de formato necesitemos manipular columnas de distintos tipos de datos, aplicando también diferentes características visuales a cada celda, puede resultar de utilidad crear en primer lugar un estilo para el tipo de dato a formatear, en el que configuremos cada uno de los aspectos visuales, y aplicarlo en el evento CellFormatting al detectar que la celda actual contiene dicho tipo de dato.
Basándonos en este supuesto, dentro del siguiente ejemplo creamos dos objetos de tipo DataGridViewCellStyle, que instanciamos y configuramos al cargar el formulario, para finalmente, asignar en el evento CellFormatting, cuando la celda a manipular corresponda a dicho tipo de dato y su valor cumpla cierta condición, como vemos en el siguiente código.
public partial class frmFormatoTipoDato : Form
{
// declarar dos estilos
DataGridViewCellStyle styFecha;
DataGridViewCellStyle styDecimal;
//....
public frmFormatoTipoDato()
{
InitializeComponent();
}
private void frmFormatoTipoDato_Load(object sender, EventArgs e)
{
// instanciar un estilo para mostrar los tipos fecha y decimal
styFecha = new DataGridViewCellStyle();
styFecha.BackColor = Color.Gold;
styFecha.ForeColor = Color.DarkOliveGreen;
styFecha.Format = "dd/MMM/yyyy";
styFecha.Font = new Font("Magneto", 10, FontStyle.Bold);
styDecimal = new DataGridViewCellStyle();
styDecimal.BackColor = Color.LightGreen;
styDecimal.ForeColor = Color.DarkOrchid;
styDecimal.Format = "C";
styDecimal.Font = new Font("Lucida Calligraphy", 10);
this.dataGridView1.DataSource = ConstruirDatos.ObtenerTabla();
}
private void dataGridView1_CellFormatting(object sender, DataGridViewCellFormattingEventArgs e)
{
// comprobar el tipo de dato que contiene la celda
// y aplicarle el estilo
if (e.Value.GetType() == typeof(DateTime))
{
if (((DateTime)e.Value).Year > 1970)
{
e.CellStyle = styFecha;
}
}
if (e.Value.GetType() == typeof(decimal))
{
if ((decimal)e.Value == 30000)
{
e.CellStyle = styDecimal;
}
}
}
}
El efecto puede apreciarse en esta imagen.

Formateando mediante expresiones reguladas
A través de la clase Regex podemos construir un formato basado en un patrón de sustitución que pasamos como cadena de caracteres al constructor de la expresión regulada.
Tomemos como base para esta demostración el campo CustomerAlternateKey, que muestra un código alfanumérico. Suponiendo que necesitemos visualizar los valores de esta columna en grupos de dígitos que sigan un patrón como este: XX-XXX-XX-XXX, el código para formatear estos valores sería similar al siguiente.
using System.Text.RegularExpressions;
//....
private void dataGridView1_CellFormatting(object sender, DataGridViewCellFormattingEventArgs e)
{
if (this.dataGridView1.Columns[e.ColumnIndex].Name == "CustomerAlternateKey")
{
// crear una expresión regulada con un patrón de formato
Regex oExpRegulada = new Regex(@"(\D{2})(\d{3})(\d{2})(\d{3})");
// sustituir las partes del valor a formatear mediante la expresión regulada
e.Value = oExpRegulada.Replace(e.Value.ToString(), "$1-$2-$3-$4");
}
}
Mientras que los resultados serían los que vemos en esta imagen.

Aplicando formato a filas completas
Si el requerimiento de formato consiste en aplicarlo a la totalidad de una fila, podríamos pensar que la forma de resolver la situación pasaría por recorrer la colección Cells de cada objeto fila del DataGridView, y manipular la propiedad Style de dichas celdas individuales. Sin embargo existe un medio más fácil de lograr este objetivo, consistente en manipular, dentro del evento CellFormatting, la propiedad DefaultCellStyle del objeto DataGridViewRow actual que obtenemos de la colección Rows del control DataGridView.
private void dataGridView1_CellFormatting(object sender, DataGridViewCellFormattingEventArgs e)
{
// si la celda corresponde a los ingresos anuales
if (this.dataGridView1.Columns[e.ColumnIndex].Name == "YearlyIncome")
{
// y el valor cumple con cierta condición
if ((decimal)e.Value > 50000)
{
// aplicar formato a la totalidad de la fila
this.dataGridView1.Rows[e.RowIndex].DefaultCellStyle.BackColor = Color.Aquamarine;
}
}
}
En la imagen mostrada a continuación podemos apreciar este efecto.

Y con este ejemplo damos por concluida esta pequeña serie de artículos dedicados a las diferentes posibilidades de formato que podemos utilizar con el control DataGridView, espero que os resulte de utilidad. Al igual que en las anteriores entregas, los ejemplos están disponibles en estos enlaces: C# y VB.
Un saludo.