sábado, 21 de agosto de 2010

ASP.NET - Datos agrupados en GridView

Dentro de una grilla del tipo GridView para aplicaciones ASP.NET es posible realizar agrupados.

En este caso voy a hacer un agrupado sin duplicar el header de la grilla, o sea que manteniendo un único header voy a crear un agrupado con la información que queramos agregar en el mismo y agregando algunos botones por medio de HTML para hacerlo un poco más completo.

Ejemplo:

Esta es la grilla vista desde la página aspx, en la misma pareciera que no se está agrupando nada pero cambia la vista luego de compilarse.



El código aspx sería el siguiente:




<asp:GridView ID="Grd" runat="server" AutoGenerateColumns="False" CellSpacing="1"
CaptionAlign="Top" CellPadding="1" DataKeyNames="Col1,Col2,Col11"
CssClass="Estilo16">

<RowStyle CssClass="Estilo16" BorderStyle="Solid" />

<Columns>
<asp:BoundField DataField="Col1" HeaderText="" Visible="False"><ItemStyle Height="20px" /></asp:BoundField>
<asp:BoundField DataField="Col2" HeaderText="" Visible="False" />
<asp:BoundField HeaderText="Col3" DataField="" ReadOnly="True" ><ItemStyle Width="12%" Height="20px" /></asp:BoundField>
<asp:BoundField DataField="Col4" HeaderText="" ReadOnly="True" ><ItemStyle Width="34%" Height="20px" /></asp:BoundField>
<asp:BoundField DataField="Col5" HeaderText="" ReadOnly="True" ><ItemStyle Width="10%" Height="20px" /></asp:BoundField>
<asp:BoundField DataField="Col6" HeaderText="" ReadOnly="True" ><ItemStyle Width="7%" Height="20px" /></asp:BoundField>
<asp:BoundField DataField="Col7" HeaderText="" ReadOnly="True" ><ItemStyle Width="7%" Height="20px" /></asp:BoundField>
<asp:BoundField DataField="Col8" HeaderText="" ReadOnly="True" ><ItemStyle Width="7%" Height="20px" /></asp:BoundField>
<asp:BoundField DataField="Col9" HeaderText="" ReadOnly="True" ><ItemStyle Width="5%" Height="20px" /></asp:BoundField>
<asp:BoundField DataField="Col10" HeaderText="" ReadOnly="True" ><ItemStyle Width="10%" Height="20px" /></asp:BoundField>
<asp:CommandField ButtonType="Image" HeaderText="" SelectImageUrl="~/imagenes/lupa.gif" ShowSelectButton="True" ><ItemStyle Width="5%" Height="20px" /></asp:CommandField>
<asp:CommandField ButtonType="Image" DeleteImageUrl="~/imagenes/btnBaja.png" HeaderText="" ShowDeleteButton="True" ><ItemStyle Width="4%" Height="20px" /></asp:CommandField>
<asp:BoundField DataField="Col10" HeaderText="" Visible="False" ReadOnly="True" />
<asp:BoundField DataField="Col11" HeaderText="" Visible="False" />
</Columns>
<HeaderStyle BackColor="#E8E8E8" CssClass="tabla" Height="29px" />
</asp:GridView>



Este es el código VB:




Private Sub Grd_RowDataBound(ByVal sender As Object, ByVal e As System.Web.UI.WebControls.GridViewRowEventArgs) Handles Grd.RowDataBound
If e.Row.RowType = DataControlRowType.DataRow Then
Dim DRowV As DataRowView = e.Row.DataItem
Dim unColorFila As New Color

' Este código se utiliza con la recuperación de algunas columnas de un Stored procedure.

If Not IsDBNull(DRowV("NumeroCC")) Then
If DRowV("NumeroCC") > 0 Then
If Not IsDBNull(DRowV("Numero")) Then
If DRowV("Numero").ToString.Length > 0 Then
e.Row.Cells(4).Text = DRowV("NumeroCC").ToString & " - " & DRowV("Numero").ToString
End If
Else
e.Row.Cells(4).Text = DRowV("NumeroCC").ToString
End If
End If
End If

unColorFila = Color.FromArgb(255, 246, 246, 246)

If Not IsDBNull(DRowV("FechaVto")) And Not IsDBNull(DRowV("Cantidad")) And Not IsDBNull(DRowV("CantidadEntregada")) Then
If CType(DRowV("FechaVto"), Date) < Date.Now Then unColorFila = Color.FromArgb(255, 255, 229, 179)
If (CType(DRowV("Cantidad"), Decimal) <= CType(DRowV("CantidadEntregada"), Decimal)) Then unColorFila = Color.FromArgb(255, 232, 251, 227)
End If

e.Row.BackColor = unColorFila

If Not IsDBNull(DRowV("fecha")) Then
e.Row.Cells(5).Text = CType(DRowV("fecha"), Date).ToShortDateString
End If

If Not IsDBNull(DRowV("fechaVto")) Then
e.Row.Cells(6).Text = CType(DRowV("fechaVto"), Date).ToShortDateString
End If

If Not IsDBNull(DRowV("FechaAsignacion")) Then
e.Row.Cells(7).Text = CType(DRowV("FechaAsignacion"), Date).ToShortDateString
End If

'--------------------------------------------------------------------------------------

Dim table As Table = Grd.Controls(0)

'For Each row As GridViewRow In Grd.Rows

Dim realIndex As Int16 = table.Rows.GetRowIndex(e.Row)

Dim currentEmisor As String = Grd.DataKeys(e.Row.RowIndex).Values(0)
Dim currentID As Long = CType(Grd.DataKeys(e.Row.RowIndex).Values(2), Long)

' Estos son los campos para el agrupado.
If currentEmisor <> lastEmisor Or currentID <> lastID Then
' Acá creo la fila que va a cumplir la función del agrupado.
Dim groupHeaderRow As GridViewRow = New GridViewRow(realIndex, realIndex, DataControlRowType.Separator, DataControlRowState.Normal)
Dim newCell(2) As TableCell

' Agrupado con 2 columnas y un link
newCell(0) = New TableCell
newCell(0).ColumnSpan = 4
newCell(0).HorizontalAlign = HorizontalAlign.Left
newCell(0).CssClass = "tabla_botonera1"
newCell(0).Font.Bold = True
newCell(0).ControlStyle.BorderColor = Color.Transparent
newCell(0).ControlStyle.BorderStyle = BorderStyle.Solid
newCell(0).ControlStyle.BorderWidth = 0

If Not IsDBNull(DRowV("CompraDirecta")) Then
If DRowV("CompraDirecta").ToString = "1" Then
newCell(0).Text = "<span class=textoGris>&nbsp;&nbsp;Número: </span> <span class=txtgeneral>" & Grd.DataKeys(e.Row.RowIndex).Values(1) & "</span><span class=Estilo28>&nbsp;&nbsp;&nbsp;(Compra Directa)</span><span class=txtgeneral>&nbsp;&nbsp;&nbsp;" & currentEmisor & "</span><span class=mano onClick=MM_openBrWindow('Archivos_adjuntos.aspx?Id=" & currentID & "&ID_Nro=" & DRowV("Nro") & "','Archivos','resizable=yes','540','300','true')><strong>&nbsp;&nbsp;&nbsp;Archivos Adjuntos</strong></span>"
'newCell(0).Text = "<span class=textoGris>&nbsp;&nbsp;Número: </span> <span class=txtgeneral>" & Grd.DataKeys(e.Row.RowIndex).Values(1) & "</span><span class=Estilo28>&nbsp;&nbsp;&nbsp;(Compra Directa)</span><span class=txtgeneral>&nbsp;&nbsp;&nbsp;" & currentCategory & "</span><asp:linkbutton runat=server ID=lnkAdjuntos Text=Archivos Adjuntos cssclass=mano/>"
Else
newCell(0).Text = "<span class=textoGris>&nbsp;&nbsp;Número: </span> <span class=txtgeneral>" & Grd.DataKeys(e.Row.RowIndex).Values(1) & "</span><span class=txtgeneral>&nbsp;&nbsp;&nbsp;" & currentEmisor & "</span><span class=mano onClick=MM_openBrWindow('Archivos_adjuntos.aspx?Id=" & currentID & "&ID_Nro=" & DRowV("Nro") & "','Archivos','resizable=yes','540','300','true')><strong>&nbsp;&nbsp;&nbsp;Archivos Adjuntos</strong></span>"
'newCell(0).Text = "<span class=textoGris>&nbsp;&nbsp;Número: </span> <span class=txtgeneral>" & Grd.DataKeys(e.Row.RowIndex).Values(1) & "</span><span class=txtgeneral>&nbsp;&nbsp;&nbsp;" & currentCategory & "</span><asp:linkbutton runat=server ID=lnkAdjuntos Text=Archivos Adjuntos cssclass=mano/>"
End If
Else
newCell(0).Text = "<span class=textoGris>&nbsp;&nbsp;Número: </span> <span class=txtgeneral>" & Grd.DataKeys(e.Row.RowIndex).Values(1) & "</span><span class=txtgeneral>&nbsp;&nbsp;&nbsp;" & currentEmisor & "</span><span class=mano onClick=MM_openBrWindow('Archivos_adjuntos.aspx?Id=" & currentID & "&ID_Nro=" & DRowV("Nro") & "','Archivos','resizable=yes','540','300','true')><strong>&nbsp;&nbsp;&nbsp;Archivos Adjuntos</strong></span>"
'newCell(0).Text = "<span class=textoGris>&nbsp;&nbsp;Número: </span> <span class=txtgeneral>" & Grd.DataKeys(e.Row.RowIndex).Values(1) & "</span><span class=txtgeneral>&nbsp;&nbsp;&nbsp;" & currentCategory & "</span><asp:linkbutton runat=server ID=lnkAdjuntos Text=Archivos Adjuntos cssclass=mano/>"
End If
'onClick=MM_openBrWindow('Archivos_adjuntos.aspx','Archivos','resizable=yes','540','300','true')

' Columna con botón imprimir
newCell(1) = New TableCell
newCell(1).ColumnSpan = 2
newCell(1).VerticalAlign = VerticalAlign.Middle
newCell(1).HorizontalAlign = HorizontalAlign.Left
newCell(1).CssClass = "tabla_botonera1"
newCell(1).ControlStyle.BorderColor = Color.Transparent
newCell(1).ControlStyle.BorderStyle = BorderStyle.Solid
newCell(1).ControlStyle.BorderWidth = 0

If Not IsDBNull(DRowV("id_Urgencia")) Then
If DRowV("id_Urgencia").ToString = "1" Then
newCell(1).Text = "<img src=imagenes/Print.png width=16 height=16 align=absmiddle class=mano onClick=MM_openBrWindow('Imprimir.aspx?id=" & currentID & "','Imprimir','resizable=yes','800','600','true')><strong><span class=Estilo26>&nbsp;&nbsp;&nbsp;Urgente</span></strong>"
Else
newCell(1).Text = "<img src=imagenes/Print.png width=16 height=16 align=absmiddle class=mano onClick=MM_openBrWindow('Imprimir.asp?id=" & currentID & "','Imprimir','resizable=yes','800','600','true')>"
End If
Else
newCell(1).Text = "<img src=imagenes/Print.png width=16 height=16 align=absmiddle class=mano onClick=MM_openBrWindow('Imprimir.asp?id=" & currentID & "','Imprimir','resizable=yes','800','600','true')>"
End If

' Columna con nivel de urgencia
newCell(2) = New TableCell
newCell(2).ColumnSpan = 4
newCell(2).VerticalAlign = VerticalAlign.Middle
newCell(2).HorizontalAlign = HorizontalAlign.Left
newCell(2).CssClass = "tabla_botonera1"
newCell(2).ControlStyle.BorderColor = Color.Transparent
newCell(2).ControlStyle.BorderStyle = BorderStyle.Solid
newCell(2).ControlStyle.BorderWidth = 0

If Not IsDBNull(DRowV("id_Estado")) Then
If DRowV("id_Estado").ToString = "5" Then
newCell(2).Text = "<img src=imagenes/fondo_verde.png>"
Else
newCell(2).Text = "<img src=imagenes/fondo_naranja.png>"
End If
Else
newCell(2).Text = "<img src=imagenes/fondo_naranja.png>"
End If

groupHeaderRow.Cells.AddRange(newCell)

table.Controls.AddAt(realIndex, groupHeaderRow)

lastEmisor = currentEmisor
lastID = currentID
End If
End If

End Sub




Espero que con este código puedan crear sus propios agrupados, de una manera quizás más sencilla o algo bien completo para que la grilla sea bien útil y atractiva.

Saludos.

Mariano Llarin.-
Neuquén, Argentina.

2 comentarios:

  1. Hola tengo problemas con los Index sabes como solucionar eso? gracias.

    ResponderEliminar
    Respuestas
    1. Hola, que tipo de problema? Si es posible pega algo de código para identificar que puede ser?

      Saludos,

      Eliminar