Exibir informações de resumo no rodapé do GridView (C#)
por Scott Mitchell
As informações de resumo geralmente são exibidas na parte inferior do relatório em uma linha de resumo. O controle GridView pode incluir uma linha de rodapé em cujas células podemos injetar dados agregados programaticamente. Neste tutorial, veremos como exibir dados agregados nesta linha de rodapé.
Introdução
Além de ver cada um dos preços dos produtos, unidades em estoque, unidades em ordem e níveis de reordenação, um usuário também pode estar interessado em informações de agregação, como o preço médio, o número total de unidades em estoque e assim por diante. Essas informações resumidas geralmente são exibidas na parte inferior do relatório em uma linha de resumo. O controle GridView pode incluir uma linha de rodapé em cujas células podemos injetar dados agregados programaticamente.
Esta tarefa nos apresenta três desafios:
- Configurando o GridView para exibir sua linha de rodapé
- Determinando os dados de resumo; ou seja, como calcular o preço médio ou o total das unidades em estoque?
- Injetando os dados de resumo nas células apropriadas da linha do rodapé
Neste tutorial, veremos como superar esses desafios. Especificamente, criaremos uma página que lista as categorias em uma lista suspensa com os produtos da categoria selecionada exibidos em um GridView. O GridView incluirá uma linha de rodapé que mostra o preço médio e o número total de unidades em estoque e na ordem dos produtos nessa categoria.
Figura 1: As informações de resumo são exibidas na linha rodapé do GridView (clique para exibir a imagem em tamanho real)
Este tutorial, com sua categoria para produtos master/interface de detalhes, baseia-se nos conceitos abordados no tutorial anterior de Filtragem De Mestre/Detalhes com um DropDownList. Se você ainda não trabalhou no tutorial anterior, faça isso antes de continuar com este.
Etapa 1: Adicionar as categorias DropDownList e Products GridView
Antes de nos preocuparmos com a adição de informações resumidas ao rodapé do GridView, vamos primeiro simplesmente criar o relatório de master/detalhes. Depois de concluirmos esta primeira etapa, veremos como incluir dados de resumo.
Comece abrindo a SummaryDataInFooter.aspx
página na CustomFormatting
pasta . Adicione um controle DropDownList e defina como ID
Categories
. Em seguida, clique no link Escolher Fonte de Dados na marca inteligente do DropDownList e opte por adicionar um novo ObjectDataSource chamado CategoriesDataSource
que invoca o CategoriesBLL
método da GetCategories()
classe.
Figura 2: Adicionar um novo objetoDataSource nomeado CategoriesDataSource
(clique para exibir a imagem em tamanho real)
Figura 3: Fazer com que o ObjectDataSource invoque o CategoriesBLL
método da GetCategories()
classe (clique para exibir a imagem em tamanho real)
Depois de configurar o ObjectDataSource, o assistente nos retorna ao assistente de Configuração de Fonte de Dados do DropDownList do qual precisamos especificar qual valor do campo de dados deve ser exibido e qual deles deve corresponder ao valor do DropDownList ListItem
. Tenha o CategoryName
campo exibido e use o CategoryID
como o valor .
Figura 4: use os CategoryName
campos e CategoryID
como e Text
Value
para os ListItem
s, respectivamente (clique para exibir a imagem em tamanho real)
Neste ponto, temos um DropDownList (Categories
) que lista as categorias no sistema. Agora precisamos adicionar um GridView que lista os produtos que pertencem à categoria selecionada. Antes disso, porém, tire um momento para marcar caixa de seleção Habilitar AutoPostBack na marca inteligente do DropDownList. Conforme discutido no tutorial Filtragem Mestre/Detalhe com um DropDownList , a definição da propriedade dropDownList AutoPostBack
para true
a página será postada novamente sempre que o valor DropDownList for alterado. Isso fará com que o GridView seja atualizado, mostrando esses produtos para a categoria recém-selecionada. Se a AutoPostBack
propriedade estiver definida false
como (o padrão), alterar a categoria não causará um postback e, portanto, não atualizará os produtos listados.
Figura 5: Marque a caixa de seleção Habilitar AutoPostBack na Marca Inteligente do DropDownList (Clique para exibir a imagem em tamanho real)
Adicione um controle GridView à página para exibir os produtos para a categoria selecionada. Defina o GridView como ID
ProductsInCategory
e associe-o a um novo ObjectDataSource chamado ProductsInCategoryDataSource
.
Figura 6: Adicionar um novo objetoDataSource nomeado ProductsInCategoryDataSource
(clique para exibir a imagem em tamanho real)
Configure o ObjectDataSource para que ele invoque o ProductsBLL
método da GetProductsByCategoryID(categoryID)
classe.
Figura 7: Fazer com que ObjectDataSource invoque o GetProductsByCategoryID(categoryID)
método (clique para exibir a imagem em tamanho real)
Como o GetProductsByCategoryID(categoryID)
método usa um parâmetro de entrada, na etapa final do assistente, podemos especificar a origem do valor do parâmetro. Para exibir esses produtos da categoria selecionada, tenha o parâmetro extraído do Categories
DropDownList.
Figura 8: Obter o valor do categoryID
parâmetro da lista suspensa categorias selecionadas (clique para exibir a imagem em tamanho real)
Depois de concluir o assistente, o GridView terá um BoundField para cada uma das propriedades do produto. Vamos limpo esses BoundFields para que apenas os ProductName
Campos Associados , UnitPrice
, UnitsInStock
e UnitsOnOrder
sejam exibidos. Fique à vontade para adicionar quaisquer configurações de nível de campo aos BoundFields restantes (como formatar o UnitPrice
como uma moeda). Depois de fazer essas alterações, a marcação declarativa do GridView deve ser semelhante à seguinte:
<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>
Neste ponto, temos um relatório de master/detalhes totalmente funcional que mostra o nome, o preço unitário, as unidades em estoque e as unidades em ordem para os produtos que pertencem à categoria selecionada.
Figura 9: Obter o valor do categoryID
parâmetro da lista suspensa categorias selecionadas (clique para exibir a imagem em tamanho real)
Etapa 2: Exibindo um rodapé no GridView
O controle GridView pode exibir uma linha de cabeçalho e rodapé. Essas linhas são exibidas dependendo dos valores das ShowHeader
propriedades e ShowFooter
, respectivamente, com ShowHeader
o padrão de e ShowFooter
para true
false
. Para incluir um rodapé no GridView, basta definir sua ShowFooter
propriedade como true
.
Figura 10: Defina a Propriedade GridView ShowFooter
como true
(Clique para exibir a imagem em tamanho real)
A linha de rodapé tem uma célula para cada um dos campos definidos no GridView; no entanto, essas células estão vazias por padrão. Reserve um momento para ver nosso progresso em um navegador. Com a ShowFooter
propriedade agora definida como true
, o GridView inclui uma linha de rodapé vazia.
Figura 11: O GridView agora inclui uma linha de rodapé (clique para exibir a imagem em tamanho real)
A linha de rodapé na Figura 11 não se destaca, pois tem um plano de fundo branco. Vamos criar uma FooterStyle
classe CSS em Styles.css
que especifica uma tela de fundo vermelha escura e, em seguida, configurar o GridView.skin
arquivo Skin no DataWebControls
Tema para atribuir essa classe CSS à propriedade do FooterStyle
CssClass
GridView. Se você precisar se atualizar sobre Skins e Temas, consulte o tutorial Exibindo dados com o ObjectDataSource .
Comece adicionando a seguinte classe CSS a Styles.css
:
.FooterStyle
{
background-color: #a33;
color: White;
text-align: right;
}
A FooterStyle
classe CSS é semelhante em estilo à HeaderStyle
classe , embora a HeaderStyle
cor da tela de fundo seja sutileza mais escura e seu texto seja exibido em uma fonte em negrito. Além disso, o texto no rodapé é alinhado à direita, enquanto o texto do cabeçalho é centralizado.
Em seguida, para associar essa classe CSS ao rodapé de cada GridView, abra o GridView.skin
arquivo no DataWebControls
Tema e defina a FooterStyle
propriedade do CssClass
. Após essa adição, a marcação do arquivo deverá ser semelhante a:
<asp:GridView runat="server" CssClass="DataWebControlStyle">
<AlternatingRowStyle CssClass="AlternatingRowStyle" />
<RowStyle CssClass="RowStyle" />
<HeaderStyle CssClass="HeaderStyle" />
<FooterStyle CssClass="FooterStyle" />
<SelectedRowStyle CssClass="SelectedRowStyle" />
</asp:GridView>
Como mostra a captura de tela abaixo, essa alteração faz com que o rodapé se destaque mais claramente.
Figura 12: a linha de rodapé do GridView agora tem uma cor de tela de fundo avermelhada (clique para exibir a imagem em tamanho real)
Etapa 3: Computando os dados de resumo
Com o rodapé do GridView exibido, o próximo desafio enfrentado é como calcular os dados de resumo. Há duas maneiras de calcular essas informações de agregação:
Por meio de uma consulta SQL, podemos emitir uma consulta adicional ao banco de dados para calcular os dados de resumo de uma determinada categoria. O SQL inclui várias funções de agregação junto com uma
GROUP BY
cláusula para especificar os dados sobre os quais os dados devem ser resumidos. A consulta SQL a seguir traria de volta as informações necessárias:SELECT CategoryID, AVG(UnitPrice), SUM(UnitsInStock), SUM(UnitsOnOrder) FROM Products WHERE CategoryID = categoryID GROUP BY CategoryID
É claro que você não gostaria de emitir essa consulta diretamente da
SummaryDataInFooter.aspx
página, mas sim criando um método noProductsTableAdapter
e noProductsBLL
.Compute essas informações conforme elas estão sendo adicionadas ao GridView, conforme discutido no tutorial Formatação Personalizada Baseada em Dados , o manipulador de eventos do
RowDataBound
GridView é acionado uma vez para cada linha que está sendo adicionada ao GridView após sua entrada de dados. Ao criar um manipulador de eventos para esse evento, podemos manter um total em execução dos valores que queremos agregar. Depois que a última linha de dados tiver sido associada ao GridView, temos os totais e as informações necessárias para calcular a média.
Normalmente, emprendo a segunda abordagem, pois ela salva uma viagem ao banco de dados e o esforço necessário para implementar a funcionalidade de resumo na Camada de Acesso a Dados e na Camada lógica de negócios, mas qualquer abordagem seria suficiente. Para este tutorial, vamos usar a segunda opção e acompanhar o total em execução usando o RowDataBound
manipulador de eventos.
Crie um RowDataBound
manipulador de eventos para o GridView selecionando GridView no Designer, clicando no ícone de raio do janela Propriedades e clicando duas vezes no RowDataBound
evento. Isso criará um manipulador de eventos chamado ProductsInCategory_RowDataBound
na SummaryDataInFooter.aspx
classe code-behind da página.
protected void ProductsInCategory_RowDataBound
(object sender, GridViewRowEventArgs e)
{
}
Para manter um total em execução, precisamos definir variáveis fora do escopo do manipulador de eventos. Crie as quatro variáveis de nível de página a seguir:
_totalUnitPrice
, do tipodecimal
_totalNonNullUnitPriceCount
, do tipoint
_totalUnitsInStock
, do tipoint
_totalUnitsOnOrder
, do tipoint
Em seguida, escreva o código para incrementar essas três variáveis para cada linha de dados encontrada no RowDataBound
manipulador de eventos.
// Class-scope, running total variables...
decimal _totalUnitPrice = 0m;
int _totalNonNullUnitPriceCount = 0;
int _totalUnitsInStock = 0;
int _totalUnitsOnOrder = 0;
protected void ProductsInCategory_RowDataBound(object sender,
GridViewRowEventArgs e)
{
if (e.Row.RowType == DataControlRowType.DataRow)
{
// Reference the ProductsRow via the e.Row.DataItem property
Northwind.ProductsRow product =
(Northwind.ProductsRow)
((System.Data.DataRowView)e.Row.DataItem).Row;
// Increment the running totals (if they are not NULL!)
if (!product.IsUnitPriceNull())
{
_totalUnitPrice += product.UnitPrice;
_totalNonNullUnitPriceCount++;
}
if (!product.IsUnitsInStockNull())
_totalUnitsInStock += product.UnitsInStock;
if (!product.IsUnitsOnOrderNull())
_totalUnitsOnOrder += product.UnitsOnOrder;
}
}
O RowDataBound
manipulador de eventos começa garantindo que estamos lidando com um DataRow. Depois que isso for estabelecido, a Northwind.ProductsRow
instância que acabou de ser associada ao GridViewRow
objeto em e.Row
será armazenada na variável product
. Em seguida, as variáveis totais em execução são incrementadas pelos valores correspondentes do produto atual (supondo que elas não contenham um valor de banco de dados NULL
). Controlamos o total em execução UnitPrice
e o número de registros nãoNULL
UnitPrice
, pois o preço médio é o quociente desses dois números.
Etapa 4: Exibindo os dados de resumo no rodapé
Com os dados de resumo totalizados, a última etapa é exibi-los na linha de rodapé do GridView. Essa tarefa também pode ser realizada programaticamente por meio do RowDataBound
manipulador de eventos. Lembre-se de que o RowDataBound
manipulador de eventos é acionado para cada linha associada ao GridView, incluindo a linha de rodapé. Portanto, podemos aumentar nosso manipulador de eventos para exibir os dados na linha de rodapé usando o seguinte código:
protected void ProductsInCategory_RowDataBound
(object sender, GridViewRowEventArgs e)
{
if (e.Row.RowType == DataControlRowType.DataRow)
{
... Increment the running totals ...
}
else if (e.Row.RowType == DataControlRowType.Footer)
{
... Display the summary data in the footer ...
}
}
Como a linha de rodapé é adicionada ao GridView depois que todas as linhas de dados tiverem sido adicionadas, podemos ter certeza de que, quando estivermos prontos para exibir os dados de resumo no rodapé, os cálculos totais em execução terão sido concluídos. A última etapa, então, é definir esses valores nas células do rodapé.
Para exibir o texto em uma célula de rodapé específica, use e.Row.Cells[index].Text = value
, em que a Cells
indexação começa em 0. O código a seguir calcula o preço médio (o preço total dividido pelo número de produtos) e o exibe junto com o número total de unidades em estoque e unidades em ordem nas células de rodapé apropriadas do GridView.
protected void ProductsInCategory_RowDataBound
(object sender, GridViewRowEventArgs e)
{
if (e.Row.RowType == DataControlRowType.DataRow)
{
... <i>Increment the running totals</i> ...
}
else if (e.Row.RowType == DataControlRowType.Footer)
{
// Determine the average UnitPrice
decimal avgUnitPrice = _totalUnitPrice / (decimal) _totalNonNullUnitPriceCount;
// Display the summary data in the appropriate cells
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();
}
}
A Figura 13 mostra o relatório depois que esse código é adicionado. Observe como o ToString("c")
faz com que as informações de resumo de preço médio sejam formatadas como uma moeda.
Figura 13: a linha de rodapé do GridView agora tem uma cor da tela de fundo avermelhada (clique para exibir a imagem em tamanho real)
Resumo
Exibir dados de resumo é um requisito de relatório comum e o controle GridView facilita a inclusão dessas informações em sua linha de rodapé. A linha de rodapé é exibida quando a propriedade gridView ShowFooter
é definida true
como e pode ter o texto em suas células definido programaticamente por meio do RowDataBound
manipulador de eventos. A computação dos dados de resumo pode ser feita consultando novamente o banco de dados ou usando código na classe code-behind da página ASP.NET para calcular programaticamente os dados de resumo.
Este tutorial conclui nosso exame da formatação personalizada com os controles GridView, DetailsView e FormView. Nosso próximo tutorial inicia nossa exploração de inserção, atualização e exclusão de dados usando esses mesmos controles.
Programação feliz!
Sobre o autor
Scott Mitchell, autor de sete livros do ASP/ASP.NET e fundador da 4GuysFromRolla.com, trabalha com tecnologias da Microsoft Web desde 1998. Scott trabalha como consultor independente, treinador e escritor. Seu último livro é Sams Teach Yourself ASP.NET 2.0 em 24 Horas. Ele pode ser contatado em mitchell@4GuysFromRolla.com. ou através de seu blog, que pode ser encontrado em http://ScottOnWriting.NET.
Comentários
https://aka.ms/ContentUserFeedback.
Brevemente: Ao longo de 2024, vamos descontinuar progressivamente o GitHub Issues como mecanismo de feedback para conteúdos e substituí-lo por um novo sistema de feedback. Para obter mais informações, veja:Submeter e ver comentários