Mostrar información de resumen en el pie de página de GridView (VB)
por Scott Mitchell
La información de resumen se muestra a menudo en la parte inferior del informe en una fila de resumen. El control GridView puede incluir una fila de pie de página en cuyas celdas se pueden insertar datos agregados mediante programación. En este tutorial veremos cómo mostrar datos agregados en esta fila de pie de página.
Introducción
Además de ver los precios de cada uno de los productos, unidades en existencias, unidades de pedido y reordenar niveles, un usuario también podría estar interesado en la información agregada, como el precio medio, el número total de unidades en existencias, etc. Esta información de resumen se muestra a menudo en la parte inferior del informe en una fila de resumen. El control GridView puede incluir una fila de pie de página en cuyas celdas se pueden insertar datos agregados mediante programación.
Esta tarea presenta tres desafíos:
- Configuración de GridView para mostrar su fila de pie de página
- Determinar los datos de resumen; es decir, ¿cómo calculamos el precio medio o el total de las unidades en existencias?
- Inserción de los datos de resumen en las celdas adecuadas de la fila de pie de página
En este tutorial veremos cómo superar estos desafíos. En concreto, crearemos una página que enumera las categorías de una lista desplegable con los productos de la categoría seleccionada que se muestran en GridView. GridView incluirá una fila de pie de página que muestra el precio medio y el número total de unidades en stock y en el pedido de productos de esa categoría.
Ilustración 1: la información de resumen se muestra en la fila pie de página de GridView (haga clic para ver la imagen a tamaño completo)
Este tutorial, con su categoría a la interfaz de maestro y detalle de productos, se basa en los conceptos descritos en el tutorial anterior Filtrado de maestros y detalles con una DropDownList. Si aún no ha trabajado en el tutorial anterior, hágalo antes de continuar con este.
Paso 1: agregar las categorías DropDownList y Products GridView
Antes de hablar con nosotros mismos con la adición de información de resumen al pie de página de GridView, primero vamos a crear el informe maestro/detalle. Una vez completado este primer paso, veremos cómo incluir datos de resumen.
Para empezar, abra la página SummaryDataInFooter.aspx
en la carpeta CustomFormatting
. Agregue un control DropDownList y establezca su ID
en Categories
. A continuación, haga clic en el vínculo Elegir origen de datos de la etiqueta inteligente DropDownList y opte por agregar un nuevo ObjectDataSource denominado CategoriesDataSource
que invoca el método GetCategories()
de la clase CategoriesBLL
.
Ilustración 2: adición de un nuevo elemento ObjectDataSource denominado CategoriesDataSource
(haga clic para ver la imagen a tamaño completo)
Ilustración 3: hacer que ObjectDataSource invoque el método GetCategories()
de la clase CategoriesBLL
(Haga clic para ver la imagen a tamaño completo)
Después de configurar ObjectDataSource, el asistente nos devuelve al asistente para configuración del origen de datos de DropDownList desde el que es necesario especificar qué valor de campo de datos se debe mostrar y cuál debe corresponder al valor del ListItem
de DropDownList. Haga que se muestre el campo CategoryName
y use el CategoryID
como valor.
Ilustración 4: use los campos CategoryName
y CategoryID
como Text
y Value
para los ListItem
, respectivamente (Haga clic para ver la imagen a tamaño completo)
En este punto tenemos un DropDownList (Categories
) que enumera las categorías del sistema. Ahora es necesario agregar una clase GridView que muestre los productos que pertenecen a la categoría seleccionada. Sin embargo, antes de hacerlo, dedique un momento a activar la casilla Habilitar AutoPostBack en la etiqueta inteligente DropDownList. Como se describe en el tutorial Filtrado de maestros y detalles con un DropDownList, estableciendo la propiedad AutoPostBack
de DropDownList en True
la página se publicará cada vez que se cambie el valor DropDownList. Esto hará que GridView se actualice, mostrando esos productos para la categoría recién seleccionada. Si la propiedad AutoPostBack
está establecida en False
(valor predeterminado), cambiar la categoría no provocará una devolución de entrada y, por tanto, no actualizará los productos enumerados.
Ilustración 5: active la casilla Habilitar AutoPostBack en la etiqueta inteligente de DropDownList (Haga clic para ver la imagen a tamaño completo)
Agregue un control GridView a la página para mostrar los productos de la categoría seleccionada. Establezca el ID
de GridView en ProductsInCategory
y enlácelo a un nuevo ObjectDataSource denominado ProductsInCategoryDataSource
.
Ilustración 6: agregar un nuevo ObjectDataSource denominado ProductsInCategoryDataSource
(Haga clic para ver la imagen a tamaño completo)
Configure ObjectDataSource para que invoque el método GetProductsByCategoryID(categoryID)
de la clase ProductsBLL
.
Ilustración 7: hacer que ObjectDataSource invoque el método GetProductsByCategoryID(categoryID)
(Haga clic para ver la imagen a tamaño completo)
Dado que el método GetProductsByCategoryID(categoryID)
toma un parámetro de entrada, en el paso final del asistente podemos especificar el origen del valor del parámetro. Para mostrar esos productos de la categoría seleccionada, tenga el parámetro extraído del DropDownList Categories
.
Ilustración 8: obtener el valor de parámetro categoryID
de las categorías seleccionadas DropDownList (Haga clic para ver la imagen a tamaño completo)
Después de completar el asistente, GridView tendrá un BoundField para cada una de las propiedades del producto. Vamos a limpiar estos BoundFields para que solo se muestren los BoundFields ProductName
, UnitPrice
, UnitsInStock
y UnitsOnOrder
. No dude en agregar cualquier configuración de nivel de campo al resto de BoundFields (por ejemplo, dar formato al UnitPrice
como moneda). Después de realizar estos cambios, el marcado declarativo de GridView debe ser similar al siguiente:
<asp:GridView ID="ProductsInCategory" runat="server" AutoGenerateColumns="False"
DataKeyNames="ProductID" DataSourceID="ProductsInCategoryDataSource"
EnableViewState="False">
<Columns>
<asp:BoundField DataField="ProductName" HeaderText="Product"
SortExpression="ProductName" />
<asp:BoundField DataField="UnitPrice" DataFormatString="{0:c}"
HeaderText="Price"
HtmlEncode="False" SortExpression="UnitPrice">
<ItemStyle HorizontalAlign="Right" />
</asp:BoundField>
<asp:BoundField DataField="UnitsInStock"
HeaderText="Units In Stock" SortExpression="UnitsInStock">
<ItemStyle HorizontalAlign="Right" />
</asp:BoundField>
<asp:BoundField DataField="UnitsOnOrder"
HeaderText="Units On Order" SortExpression="UnitsOnOrder">
<ItemStyle HorizontalAlign="Right" />
</asp:BoundField>
</Columns>
</asp:GridView>
En este punto tenemos un informe maestro/detalle totalmente funcional que muestra el nombre, el precio unitario, las unidades en existencias y las unidades para los productos que pertenecen a la categoría seleccionada.
Ilustración 9: obtener el valor de parámetro categoryID
de las categorías seleccionadas DropDownList (Haga clic para ver la imagen a tamaño completo)
Paso 2: mostrar un pie de página en GridView
El control GridView puede mostrar una fila de encabezado y pie de página. Estas filas se muestran en función de los valores de las propiedades ShowHeader
y ShowFooter
, respectivamente, con el valor predeterminado ShowHeader
para True
y ShowFooter
para False
. Para incluir un pie de página en GridView simplemente establezca su propiedad ShowFooter
en True
.
Ilustración 10: establezca la propiedad ShowFooter
de GridView en True
(Haga clic para ver la imagen a tamaño completo)
La fila de pie de página tiene una celda para cada uno de los campos definidos en GridView; sin embargo, estas celdas están vacías de forma predeterminada. Dedique un momento a ver nuestro progreso en un explorador. Con la propiedad ShowFooter
ahora establecida en True
, GridView incluye una fila de pie de página vacía.
Ilustración 11: GridView ahora incluye una fila de pie de página (Haga clic para ver la imagen a tamaño completo)
La fila de pie de página de la ilustración 11 no destaca, ya que tiene un fondo blanco. Vamos a crear una clase CSS de FooterStyle
en Styles.css
que especifique un fondo rojo oscuro y, a continuación, configure el archivo GridView.skin
Skin en el tema DataWebControls
para asignar esta clase CSS a la propiedad CssClass
de GridView FooterStyle
. Si necesita refrescar sus conocimientos sobre Skins y Temas, consulte el tutorial Visualización de datos con ObjectDataSource.
Empiece agregando la siguiente clase CSS a Styles.css
:
.FooterStyle
{
background-color: #a33;
color: White;
text-align: right;
}
La clase CSS FooterStyle
es similar en estilo a la clase HeaderStyle
, aunque el color de fondo del HeaderStyle
es más sutil y su texto se muestra en una fuente negrita. Además, el texto del pie de página está alineado a la derecha, mientras que el texto del encabezado está centrado.
A continuación, para asociar esta clase CSS a cada pie de página de GridView, abra el archivo GridView.skin
en el tema DataWebControls
y establezca la propiedad CssClass
de FooterStyle
. Después de esta adición, el marcado del archivo debe ser similar al siguiente:
<asp:GridView runat="server" CssClass="DataWebControlStyle">
<AlternatingRowStyle CssClass="AlternatingRowStyle" />
<RowStyle CssClass="RowStyle" />
<HeaderStyle CssClass="HeaderStyle" />
<FooterStyle CssClass="FooterStyle" />
<SelectedRowStyle CssClass="SelectedRowStyle" />
</asp:GridView>
Como se muestra en la captura de pantalla siguiente, este cambio hace que el pie de página destaque más claramente.
Ilustración 12: la fila pie de página de GridView ahora tiene un color de fondo rojizo (Haga clic para ver la imagen a tamaño completo)
Paso 3: calcular los datos de resumen
Con el pie de página de GridView mostrado, el siguiente desafío que nos enfrenta es cómo calcular los datos de resumen. Hay dos maneras de calcular esta información de agregado:
Mediante una consulta SQL podríamos emitir una consulta adicional a la base de datos para calcular los datos de resumen de una categoría determinada. SQL incluye una serie de funciones de agregado junto con una cláusula
GROUP BY
para especificar los datos sobre los que se deben resumir los datos. La siguiente consulta SQL devolvería la información necesaria:SELECT CategoryID, AVG(UnitPrice), SUM(UnitsInStock), SUM(UnitsOnOrder) FROM Products WHERE CategoryID = categoryID GROUP BY CategoryID
Por supuesto, no querrá emitir esta consulta directamente desde la página
SummaryDataInFooter.aspx
, sino crear un método en elProductsTableAdapter
y elProductsBLL
.Calcule esta información a medida que se agrega a GridView como se describe en el tutorial Formato personalizado basado en datos, el controlador de eventos
RowDataBound
de GridView se activa una vez para cada fila que se agrega a GridView después de su entrada de datos. Al crear un controlador de eventos para este evento, podemos mantener un total en ejecución de los valores que queremos agregar. Una vez enlazada la última fila de datos a GridView, tenemos los totales y la información necesaria para calcular el promedio.
Normalmente emplee el segundo enfoque, ya que guarda un viaje a la base de datos y el esfuerzo necesario para implementar la funcionalidad de resumen en la capa de acceso a datos y en la capa de lógica de negocios, pero cualquier enfoque sería suficiente. Para este tutorial, vamos a usar la segunda opción y realizar un seguimiento del total en ejecución mediante el controlador de eventos RowDataBound
.
Cree un controlador de eventos RowDataBound
para GridView seleccionando GridView en el Diseñador, haciendo clic en el icono de rayo en la ventana Propiedades y haciendo doble clic en el evento RowDataBound
. Como alternativa, puede seleccionar GridView y su evento RowDataBound en las listas desplegables de la parte superior del archivo de clase de código subyacente de ASP.NET. Esto creará un nuevo controlador de eventos denominado ProductsInCategory_RowDataBound
en la clase de código subyacente de la página SummaryDataInFooter.aspx
.
Protected Sub ProductsInCategory_RowDataBound _
(sender As Object, e As GridViewRowEventArgs) _
Handles ProductsInCategory.RowDataBound
End Sub
Para mantener un total en ejecución, es necesario definir variables fuera del ámbito del controlador de eventos. Cree las cuatro variables de nivel de página siguientes:
_totalUnitPrice
, de tipoDecimal
_totalNonNullUnitPriceCount
, de tipoInteger
_totalUnitsInStock
, de tipoInteger
_totalUnitsOnOrder
, de tipoInteger
A continuación, escriba el código para incrementar estas tres variables para cada fila de datos encontrada en el controlador de eventos RowDataBound
.
Dim _totalUnitPrice As Decimal = 0
Dim _totalNonNullUnitPriceCount As Integer = 0
Dim _totalUnitsInStock As Integer = 0
Dim _totalUnitsOnOrder As Integer = 0
Protected Sub ProductsInCategory_RowDataBound _
(sender As Object, e As GridViewRowEventArgs) _
Handles ProductsInCategory.RowDataBound
If e.Row.RowType = DataControlRowType.DataRow Then
Dim product As Northwind.ProductsRow = _
CType(CType(e.Row.DataItem, DataRowView).Row, Northwind.ProductsRow)
If Not product.IsUnitPriceNull() Then
_totalUnitPrice += product.UnitPrice
_totalNonNullUnitPriceCount += 1
End If
If Not product.IsUnitsInStockNull() Then
_totalUnitsInStock += product.UnitsInStock
End If
If Not product.IsUnitsOnOrderNull() Then
_totalUnitsOnOrder += product.UnitsOnOrder
End If
ElseIf e.Row.RowType = DataControlRowType.Footer Then
Dim avgUnitPrice As Decimal = _
_totalUnitPrice / CType(_totalNonNullUnitPriceCount, Decimal)
e.Row.Cells(1).Text = "Avg.: " & avgUnitPrice.ToString("c")
e.Row.Cells(2).Text = "Total: " & _totalUnitsInStock.ToString()
e.Row.Cells(3).Text = "Total: " & _totalUnitsOnOrder.ToString()
End If
End Sub
El controlador de eventos RowDataBound
comienza asegurándonos de que estamos tratando con un DataRow. Una vez que se haya establecido, la instancia Northwind.ProductsRow
que se acaba de enlazar al objeto GridViewRow
de e.Row
se almacena en la variable product
. A continuación, las variables totales en ejecución se incrementan mediante los valores correspondientes del producto actual (suponiendo que no contienen un valor NULL
de base de datos). Realizamos un seguimiento del total acumulado de UnitPrice
y del número de registros no UnitPrice
de NULL
porque el precio medio es el cociente de estos dos números.
Paso 4: mostrar los datos de resumen en el pie de página
Con los datos de resumen totales, el último paso es mostrarlo en la fila pie de página de GridView. Esta tarea también se puede realizar mediante programación a través del controlador de eventos RowDataBound
. Recuerde que el controlador de eventos RowDataBound
se activa para cada fila enlazada a GridView, incluida la fila de pie de página. Por lo tanto, podemos aumentar nuestro controlador de eventos para mostrar los datos en la fila de pie de página mediante el código siguiente:
Protected Sub ProductsInCategory_RowDataBound _
(sender As Object, e As GridViewRowEventArgs) _
Handles ProductsInCategory.RowDataBound
If e.Row.RowType = DataControlRowType.DataRow Then
... Increment the running totals ...
ElseIf e.Row.RowType = DataControlRowType.Footer
... Display the summary data in the footer ...
End If
End Sub
Puesto que la fila de pie de página se agrega a GridView una vez agregadas todas las filas de datos, podemos estar seguros de que en el momento en que estamos listos para mostrar los datos de resumen en el pie de página los cálculos totales en ejecución se habrán completado. El último paso, a continuación, es establecer estos valores en las celdas del pie de página.
Para mostrar texto en una celda de pie de página determinada, use e.Row.Cells(index).Text = value
, donde la indexación de Cells
comienza en 0. El código siguiente calcula el precio medio (el precio total dividido por el número de productos) y lo muestra junto con el número total de unidades en stock y unidades en orden en las celdas de pie de página adecuadas de GridView.
Protected Sub ProductsInCategory_RowDataBound _
(sender As Object, e As GridViewRowEventArgs) _
Handles ProductsInCategory.RowDataBound
If e.Row.RowType = DataControlRowType.DataRow Then
... <i>Increment the running totals</i> ...
ElseIf e.Row.RowType = DataControlRowType.Footer
Dim avgUnitPrice As Decimal = _
_totalUnitPrice / CType(_totalNonNullUnitPriceCount, Decimal)
e.Row.Cells(1).Text = "Avg.: " & avgUnitPrice.ToString("c")
e.Row.Cells(2).Text = "Total: " & _totalUnitsInStock.ToString()
e.Row.Cells(3).Text = "Total: " & _totalUnitsOnOrder.ToString()
End If
End Sub
En la ilustración 13 se muestra el informe después de agregar este código. Tenga en cuenta cómo el ToString("c")
hace que la información de resumen de precios promedio tenga formato como una moneda.
Ilustración 13: la fila pie de página de GridView ahora tiene un color de fondo rojizo (Haga clic para ver la imagen a tamaño completo)
Resumen
Mostrar datos de resumen es un requisito común del informe y el control GridView facilita la inclusión de dicha información en su fila de pie de página. La fila de pie de página se muestra cuando la propiedad ShowFooter
de GridView se establece en True
y puede tener el texto en sus celdas establecido mediante programación a través del controlador de eventos RowDataBound
. Para calcular los datos de resumen, puede volver a consultar la base de datos o mediante código de la clase de código subyacente de la página ASP.NET para calcular mediante programación los datos de resumen.
En este tutorial se concluye el examen del formato personalizado con los controles GridView, DetailsView y FormView. Nuestro siguiente tutorial inicia nuestra exploración de la inserción, actualización y eliminación de datos mediante estos mismos controles.
¡Feliz programación!
Acerca del autor
Scott Mitchell, autor de siete libros de ASP/ASP.NET y fundador de 4GuysFromRolla.com, ha trabajado con tecnologías web de Microsoft desde 1998. Scott trabaja como consultor independiente, entrenador y escritor. Su último libro es Sams Teach Yourself ASP.NET 2.0 in 24 Hours. Puede ponerse en contacto con él a través de mitchell@4GuysFromRolla.com. o de su blog, que se puede encontrar en http://ScottOnWriting.NET.