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.
lmblanco
Hola Enrique
Muchas gracias por haberlos leido, espero que te puedan servir de ayuda en algún momento.
Un saludo.
Luismi
anonymous
Muy didactico el árticulo lo estoy implementando en un proyecto que estoy desarrolando en mi trabajo felicitaciones.
Aprovecho para pedirte si puedes nose enviarme como trabajo los reposrtes con crystal reports del vd 2003 hace caso omiso cuando configuro el tamaño de hoja los margnes lo deja por defecto a tamaño carta. mi e-mail cglanet@hotmail.com
lmblanco
Hola Carlos
Muchas gracias por tu opinión, y celebro que te pueda ser de utilidad.
En cuanto a las cuestiones que me comentas sobre los márgenes de página con Crystal Reports, revisa este otro post:
http://geeks.ms/blogs/lmblanco/archive/2008/02/02/establecer-la-orientaci-243-n-de-p-225-gina-en-un-informe-de-crystal-reports.aspx
En el que se comenta acerca de la orientación de página del informe con este diseñador. Prueba a utilizar las opciones «Configurar página» o «Preparar impresora» del diseñador de Crystal, es posible que alguna de ellas te permita configurar los márgenes tal y como necesitas.
Un saludo.
Luismi
anonymous
Hola Miguel como estas … queria consultarte como puedo hacer para que mi datagrid tenga un parecido al grid del outlook y como puedo hacer un reporte configurable haciendo q el usuario seleccione los campos que quiere q vaya salr en el report.
Gracias un abrazo desde Perú
Carlos
lmblanco
Hola Carlos
En el siguiente enlace tienes un ejemplo de un grid con un estilo similar al de Outlook
http://www.codeproject.com/KB/miscctrl/CoolGrid.aspx
Un saludo,
Luismi
anonymous
yo al final, puesto q solo necesitaba modificar el formato de un campo lo solucione asi:
private void dtgNotas_CellFormatting(object sender, DataGridViewCellFormattingEventArgs e)
{
DataGridViewCellStyle styFecha = new DataGridViewCellStyle();
styFecha = e.CellStyle;
styFecha.Format = «dd/MM/yyyy»;
}
y listo!
asias por la info, me vino de luxe
anonymous
siento el doble post pero acabo de encontrar una forma mas directa de hacerlo en la propia entidad donde lo cargamos:
c = new DataGridViewTextBoxColumn();
c.DataPropertyName = º.FECHA;
c.HeaderText = º.FECHA;
c.Name = º.FECHA;
c.DefaultCellStyle.Format = «dd/MM/yyyy»;
c.DefaultCellStyle.Alignment = DataGridViewContentAlignment.MiddleRight;
dtg.Columns.Add(c);
dtg.Columns[º.FECHA].Width = 84;
asi nos hevitamos usar el evento cellformatting
de nuevo disculpo este post pero espero q ayude, nos vemos
lmblanco
Hola Penwin
Celebro que el artículo te haya sido útil. Esta última forma que comentas en efecto es más adecuada si quieres aplicar un estilo a todos los valores de una columna, ya que el uso de CellFormatting resulta más conveniente si quieres formatear de forma condicional ciertas celdas de la columna que cumplan una condición.
Un saludo.
Luismi
anonymous
Esta muy bien el formato y el acomodo pero si quiciera unir celdas para colocar un texto en 2 o mas celdas de un determinado renglon….??
De antemano gracias….
anonymous
Muchas gracias por el excelente artículo, era justo lo que andaba buscando, muchas gracias de verdad y sigue adelante.
lmblanco
Hola Alonso
Gracias por tu interés en el post. Para el problema que planteas, quizá te resulten de ayuda estos otros dos posts del blog.
http://geeks.ms/blogs/lmblanco/archive/2008/02/13/eliminar-los-bordes-de-separaci-243-n-de-celdas-en-el-control-datagridview.aspx
http://geeks.ms/blogs/lmblanco/archive/2008/02/02/ajustar-en-varias-l-237-neas-el-texto-de-las-celdas-en-un-control-datagridview.aspx
Un saludo.
Luismi
lmblanco
Hola Efren
Gracias por tu interés y opinión en el artículo. Celebro que te haya sido de utilidad.
Un saludo.
Luismi
anonymous
Justo lo que necesitaba, graciaaaaaaaasssssss, muy buen blog no lo habia visto, ahora me considero un aprendiz de brujo XD.
anonymous
Justo lo que necesitabaaaa, graciaaaaaaaaaaas, muy buen blog no lo había visto, ahora me considero un aprendiz de brujo XD.
lmblanco
Hola Adrián
Gracias a tí por visitar el blog, y bienvenido al grupo de aprendices de brujo 😉
Un saludo,
Luismi
anonymous
Hola una pregunta cuando intento aplicar el codigo de resaltar toda la linea me señala el siguiente error en la siguiente linea:
if ((decimal)e.Value >0)——>>>>La conversion especificada no es valida.
No entiendo pues los valores de mi columna son numeros guardados en formato number en oracle, ya intente poner Int en lugar de decimal y marca el mismo error, me puedes ayudar? Gracias.
lmblanco
Hola Moisés
Por lo que me comentas, e.Value almacena un valor numérico,
lmblanco
Hola Moisés
Por lo que me comentas, e.Value contiene un valor numérico, y al hacerle un type casting a decimal te da un error.
Dado que la fuente de datos con la que estás trabajando es Oracle, desconozco si será un problema propio del motor de datos, ya que las pruebas que yo he realizado han sido con SQL Server. Intenta, no obstante, hacer el type casting a alguno de los otros tipos numéricos disponibles, a ver si con alguno de ellos te admitiera la conversión de valores.
Un saludo,
Luismi
anonymous
muy buen post, aqui les dejo un link
uyaychay.blogspot.com
lmblanco
Hola Mario
Gracias por tu opinión y ánimo con tu blog 🙂
Un saludo,
Luismi