Partilhar via


Exibir informações de resumo no rodapé do GridView (C#)

por Scott Mitchell

Baixar PDF

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:

  1. Configurando o GridView para exibir sua linha de rodapé
  2. Determinando os dados de resumo; ou seja, como calcular o preço médio ou o total das unidades em estoque?
  3. 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.

As informações de resumo são exibidas na linha de rodapé do GridView

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 IDCategories. 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.

Adicionar um novo objetoDataSource chamado CategoriesDataSource

Figura 2: Adicionar um novo objetoDataSource nomeado CategoriesDataSource (clique para exibir a imagem em tamanho real)

Faça com que ObjectDataSource Invoque o método GetCategories() da classe CategoriesBLL

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 .

Use os campos CategoryName e CategoryID como o texto e o valor dos ListItems, respectivamente

Figura 4: use os CategoryName campos e CategoryID como e TextValue 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.

Marque a caixa de seleção Habilitar AutoPostBack na Marca Inteligente do DropDownList

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 IDProductsInCategory e associe-o a um novo ObjectDataSource chamado ProductsInCategoryDataSource.

Adicionar um novo objetoDataSource 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.

Faça com que ObjectDataSource Invoque o método GetProductsByCategoryID(categoryID)

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.

Captura de tela mostrando a janela Configurar Fonte de Dados com o valor do parâmetro categoryID selecionado.

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 ProductNameCampos Associados , UnitPrice, UnitsInStocke 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.

Captura de tela mostrando o relatório GridView para os produtos que pertencem à categoria Bebidas.

Figura 9: Obter o valor do categoryID parâmetro da lista suspensa categorias selecionadas (clique para exibir a imagem em tamanho real)

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 truefalse. Para incluir um rodapé no GridView, basta definir sua ShowFooter propriedade como true.

Definir a propriedade ShowFooter do GridView 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.

O GridView agora inclui uma linha de rodapé

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 FooterStyleCssClass 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 HeaderStylecor 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 FooterStylepropriedade 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.

Captura de tela mostrando os dados de resumo na linha de rodapé do GridView formatada com uma nova cor de plano de fundo.

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:

  1. 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 no ProductsTableAdapter e no ProductsBLL.

  2. 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 tipo decimal
  • _totalNonNullUnitPriceCount, do tipo int
  • _totalUnitsInStock, do tipo int
  • _totalUnitsOnOrder, do tipo int

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ãoNULLUnitPrice , pois o preço médio é o quociente desses dois números.

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.

Captura de tela mostrando os dados de resumo na linha de rodapé do GridView formatada 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.