Cuando queremos que nuestro Gridview nos puede agrupar encabezado y que nos quede bien alineado a sus celdas correspondientes nos puede “doler” un poco esta tarea así que aquí un pequeño tip que espero sea de ayuda. A raíz de una pregunta en los grupos de noticias de ASP.NET dejo aquí los pasos a seguir con imágenes…
Mas abajo se encuentra para descargar el ejemplo
La idea…
Tenemos una tabla cuyo encabezado es así
Y queremos que nos quede asi
Agrupando y encima con dos filas …
Utilizando CSS Friendly Adapter….
Antes cabe aclarar que estoy utilizando ASP.NET 2.0 CSS Friendly Control Adapters 1.0
Por que?
Para que la tabla sea lo mas “amigable” a CSS y a Javascript (por si queremos tambien utilizar jQuery con ella) [+ info aqui]
Se renderiza…
Sin CSS Adapter | Con CSS Adapter |
Es mucho pero que este ya que genera en cada celda (TR) contenido “sucio” pudiendo tranquilamente con estilos prevenirlo
No hay que hacer mucho trabajo para agregarlo a nuestro proyectos, simplemente descargar de CodePlex: http://www.codeplex.com/cssfriendly
Y luego mirar el ejemplo que es didáctico o te descargas el ejemplo al final de este articulo que estoy utilizando.
Algunos artículos en Geeks.ms sobre este componente:
- Usando CSS Controls Adapter en ASP.NET 2.0, mejora y optimiza tu presentacion (por Segio Tarrillo)
- Accesibilidad ( III ). ASP.NET 2.0 CSS Friendly Control Adapters (por Ibon Landa)
Pasos a seguir para agrupar celdas en un encabezado (y no morir en el intento)
- Tenemos un grilla (con un listado de Jedis)
El encabezado
- Empezamos con la primera aproximación, agrupando encabezado
Queremos agrupar las tres primeras columnas y las dos ultimas.
Para ello necesitamos el atributo colSpan de las celdas de una tabla, que aqui podremos obtenerlo en el evento RowDatabound del gridview
Protected Sub GridView2_RowDataBound(ByVal sender As Object, ByVal e As System.Web.UI.WebControls.GridViewRowEventArgs) Handles GridView2.RowDataBound Select Case e.Row.RowType Case DataControlRowType.Header 'Agrupando las dos primeras columnas (col=0, col=1 y col=2) e.Row.Cells(0).ColumnSpan = 3 e.Row.Cells(1).Visible = False e.Row.Cells(2).Visible = False 'Agrupando las dos ultimas columnas (col=3 y col=4) e.Row.Cells(3).ColumnSpan = 2 e.Row.Cells(4).Visible = False End Select End Sub
Y con esto nos queda agrupados
Toma el texto de la primer columna del grupo ya que las demas no se renderizan
El HTML resultante de la parte del encabezado es:
<thead> <tr> <th class="tipoImagen" colspan="3" scope="col">Imagen</th> <th colspan="2" scope="col">Especie</th> </tr> </thead>
- Ahora necesitamos un encabezado con dos filas
Aqui podremos tener dos opciones para insertar una tabla en la celda agrupada, generando la tabla dinámicamente o insertándola- Opcion 1: Generando tabla dinámicamente
Por ejemplo para el grupo 1'Agrupando las dos primeras columnas (col=0, col=1 y col=2) e.Row.Cells(0).ColumnSpan = 3 e.Row.Cells(1).Visible = False e.Row.Cells(2).Visible = False 'Opcion 1: Generando un tabla dinamicamente Dim tableCol1 As New HtmlTable Dim fila1, fila2 As New HtmlTableRow Dim celda11, celda21, celda22, celda23 As New HtmlTableCell 'Creando la primer fila para el encabezado (a dos filas) 'y agrupo por las cantidad de columnas hijas que tenga celda11.InnerText = "Datos Personales" celda11.ColSpan = 3 fila1.Cells.Add(celda11) 'Contenido a las celdas de la fila de abajo celda21.InnerText = "Imagen" celda22.InnerText = "Nombre" celda23.InnerText = "Fecha Nac." 'Agregando celdas a las filas fila2.Cells.Add(celda21) fila2.Cells.Add(celda22) fila2.Cells.Add(celda23) tableCol1.Rows.Add(fila1) tableCol1.Rows.Add(fila2) 'Formateando tabla tableCol1.Border = "0" tableCol1.CellPadding = "0" tableCol1.CellSpacing = "0" 'Agregando una tabla generada dinamicamente a la celda 1 del encabezado 'que previamente la argupamos e.Row.Cells(0).Controls.Clear() e.Row.Cells(0).Controls.Add(tableCol1)
- Opcion 2
Aqui insertamos el html en crudo en la celda por código o hacemos una template para poder escribir el HeaderTemplate. Asi que depende de tu elección… 🙂- Opcion 2.1
El código es muy “artesanal”
'Agrupando las dos ultimas columnas (col=3 y col=4) e.Row.Cells(3).ColumnSpan = 2 e.Row.Cells(4).Visible = False 'Opcion 2: Agregando una tabla generada dinamicamente e.Row.Cells(3).Text = "<table border=0 cellpadding=0 cellspacing=0><tr><td colspan=2>Otros datos</td></tr><tr><td>Especie</td><td>GUID</td></tr></table>"
- Opcion 2.2
Creando una columna template para poder escribir en el HeaderTemplate
<asp:TemplateField> <ItemTemplate> Contenido </ItemTemplate> <HeaderTemplate> <table border=0 cellpadding=0 cellspacing=0><tr><td colspan=2>Otros datos</td></tr><tr><td>Especie</td><td>GUID</td></tr></table> </HeaderTemplate> </asp:TemplateField>
El resultado de todo esto debería ser algo así:Pero por tenemos un problema de alineación de estas celdas que están en una tabla en el encabezado (THEAD) con las celdas del cuerpo (TBODY) de nuestra tabla principal
- Opcion 2.1
- Opcion 1: Generando tabla dinámicamente
- Entonces el ultimo paso: Es Alinear las celdas del encabezado con las celda de datos mediante CSS
Utilizando unos estilos “especiales” damos formato a estas celdas/* ------------------------------------------------------------------- TIPO DE COLUMNAS PARA JEDIS 🙂 ------------------------------------------------------------------- */ /*COLUMNA: Imagen*/ .YodaGrilla .AspNet-GridView table tbody tr td.tipoImagen { width:50px; max-width:50px; text-align:center; } /* imagen dentro de la columna Imagen*/ .YodaGrilla .AspNet-GridView table tbody tr td.tipoImagen img { width:50px; height:71px; } /*COLUMNA: Nombre*/ .YodaGrilla .AspNet-GridView table tbody tr td.tipoNombre { width:100px; } .YodaGrilla .AspNet-GridView table th .tipoNombre { } /*COLUMNA: Fecha*/ .YodaGrilla .AspNet-GridView table tbody tr td.tipoFecha { width:90px; text-align:center; } /*COLUMNA: Especie*/ .YodaGrilla .AspNet-GridView table tbody tr td.tipoEspecie { width:120px; min-width:120px; text-align:center; /*background-color:Fuchsia;*/ } /*COLUMNA: Guid*/ .YodaGrilla .AspNet-GridView table tbody tr td.tipoGuid { text-align:center; /*background-color:Yellow;*/ }
El estilo hay que insertarlo tanto en las celdas del encabezado como en las celdas de datos
En las celdas de datos<asp:GridView ID="GridView4" runat="server" AutoGenerateColumns="False" CssSelectorClass="YodaGrilla" DataSourceID="ObjectDataSource4"> <Columns> <asp:ImageField DataImageUrlField="ImagenURL" HeaderText="Imagen"> <ItemStyle CssClass="tipoImagen" /> <HeaderStyle CssClass="" /> </asp:ImageField> <asp:BoundField DataField="Nombre" HeaderText="Nombre" SortExpression="Nombre"> <ItemStyle CssClass="tipoNombre" /> </asp:BoundField> <asp:BoundField DataField="FechaNacimiento" HeaderText="Fecha Nacimiento" SortExpression="FechaNacimiento"> <ItemStyle CssClass="tipoFecha" /> </asp:BoundField> <asp:BoundField DataField="Especie" HeaderText="Especie" SortExpression="Especie"> <ItemStyle CssClass="tipoEspecie" /> <HeaderStyle CssClass="" /> </asp:BoundField> <asp:BoundField DataField="Guid" HeaderText="Guid" SortExpression="Guid"> <ItemStyle CssClass="tipoGuid" /> </asp:BoundField> </Columns> </asp:GridView>
Y en las celdas del encabezado…Ya sea en la tabla generada
'Contenido a las celdas de la fila de abajo celda21.InnerText = "Imagen" celda21.Attributes.Add("class", "tipoImagen") celda22.InnerText = "Nombre" celda22.Attributes.Add("class", "tipoNombre") celda23.InnerText = "Fecha Nac." celda23.Attributes.Add("class", "tipoFecha")
Y en la tabla insertada en crudo
'Opcion 2: Agregando una tabla generada dinamicamente e.Row.Cells(3).Controls.Clear() e.Row.Cells(3).Text = "<table border=0 cellpadding=0 cellspacing=0><tr><td colspan=2>Otros datos</td></tr><tr><td class='tipoEspecie'>Especie</td><td class='tipoGuid'>GUID</td></tr></table>"
Y alli…visualizaremos
Ejemplo para la descarga
Si no funciona la incrustación de arriba click aqui
Enlaces
- Atributo ColSpan (W3C)
http://www.w3.org/TR/REC-html40/struct/tables.html#adef-colspan - HtmlTableCell.ColSpan (Propiedad)
Obtiene o establece el número de columnas que ocupa una celda representada por una instancia de la clasehttp://msdn.microsoft.com/es-es/library/system.web.ui.htmlcontrols.htmltablecell.colspan(VS.80).aspx