Compartilhar 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 os preços de cada um 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 agregadas, 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. Determinação dos dados resumidos; ou seja, como calculamos o preço médio ou o total das unidades em estoque?
  3. Injetando os dados de resumo nas células apropriadas da linha de 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 no pedido de produtos nessa categoria.

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

Figura 1: As informações resumidas são exibidas na linha de rodapé do GridView (clique para exibir a imagem em tamanho real)

Este tutorial, com sua categoria para a interface de mestre/detalhes de produtos, baseia-se nos conceitos abordados no tutorial anterior Filtragem de Mestre/Detalhes com uma Lista Suspensa . Se você ainda não trabalhou no tutorial anterior, faça-o antes de continuar com este.

Etapa 1: Adicionando 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 mestre/detalhado. Depois de concluir essa primeira etapa, veremos como incluir dados resumidos.

Comece abrindo a SummaryDataInFooter.aspx CustomFormatting página na pasta. Adicione um controle DropDownList e defina-o ID como 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.

Adicionar um novo ObjectDataSource chamado CategoriesDataSource

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

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

Figura 3: Fazer com que o ObjectDataSource invoque o método da GetCategories() classe (clique para exibir a CategoriesBLL imagem em tamanho completo)

Depois de configurar o ObjectDataSource, o assistente nos retorna ao assistente de Configuração de Fonte de Dados do DropDownList, a partir do qual precisamos especificar qual valor de campo de dados deve ser exibido e qual deve corresponder ao valor do s do ListItem DropDownList. Exiba o CategoryName campo e use o CategoryID como valor.

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

Figura 4: Use os CategoryName campos e CategoryID como o Text e Value para o s, respectivamente (clique para exibir a ListItem 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 de fazermos isso, porém, reserve um momento para marcar a caixa de seleção Habilitar AutoPostBack na marca inteligente do DropDownList. Conforme discutido no tutorial Filtragem mestre/detalhada com um DropDownList , definindo a propriedade do DropDownList AutoPostBack como true a página será postada de volta 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 como false (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 Ativar 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 da categoria selecionada. Defina o GridView ID como ProductsInCategory e associe-o a um novo ObjectDataSource chamado ProductsInCategoryDataSource.

Adicionar um novo ObjectDataSource chamado ProductsInCategoryDataSource

Figura 6: Adicionar um novo ObjectDataSource 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 o ObjectDataSource invoque o método GetProductsByCategoryID(categoryID)

Figura 7: Fazer com que o ObjectDataSource invoque o método (clique para exibir a GetProductsByCategoryID(categoryID) imagem em tamanho completo)

Como o GetProductsByCategoryID(categoryID) método recebe 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, faça com que o parâmetro seja 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 categoryID valor do parâmetro da lista suspensa de categorias selecionadas (clique para exibir a imagem em tamanho completo)

Depois de concluir o assistente, o GridView terá um BoundField para cada uma das propriedades do produto. Vamos limpar esses BoundFields para que apenas os ProductNameUnitPrice, , UnitsInStocke UnitsOnOrder BoundFields sejam exibidos. Sinta-se à vontade para adicionar qualquer configuração de nível de campo aos BoundFields restantes (como formatar o UnitPrice como 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 mestre/detalhado 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 de 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 para true e ShowFooter para false. Para incluir um rodapé no GridView, basta definir sua ShowFooter propriedade como true.

Definir a propriedade ShowFooter do GridView como true

Figura 10: Definir a propriedade do ShowFooter GridView como true (clique para exibir a imagem em tamanho completo)

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 fundo branco. Vamos criar uma FooterStyle classe CSS que Styles.css especifica um plano de fundo vermelho escuro e, em seguida, configurar o GridView.skin arquivo Skin no DataWebControls Theme para atribuir essa classe CSS à propriedade do CssClass GridViewFooterStyle. Se você precisar revisar Skins e Themes, 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 de fundo do seja sutilmente mais escura e seu texto seja exibido 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 a cada rodapé do 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 deve ficar assim:

<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 com mais clareza.

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 fundo avermelhada (clique para exibir a imagem em tamanho real)

Etapa 3: Calculando os dados resumidos

Com o rodapé do GridView exibido, o próximo desafio que enfrentamos é como calcular os dados resumidos. Há duas maneiras de calcular essas informações agregadas:

  1. Por meio de uma consulta SQL, poderíamos emitir uma consulta adicional ao banco de dados para calcular os dados resumidos de uma categoria específica. O SQL inclui várias funções agregadas junto com uma GROUP BY cláusula para especificar os dados sobre os quais os dados devem ser resumidos. A seguinte consulta SQL 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 e no ProductsTableAdapter ProductsBLL.

  2. Calcule essas informações à medida que elas estão sendo adicionadas ao GridView, conforme discutido no tutorial Formatação personalizada com base em dados , o manipulador de eventos do RowDataBound GridView é acionado uma vez para cada linha que está sendo adicionada ao GridView depois que ele foi associado a 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, teremos os totais e as informações necessárias para calcular a média.

Normalmente, emprego a segunda abordagem, pois ela economiza 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 de Lógica de Negócios, mas qualquer uma das abordagens seria suficiente. Para este tutorial, vamos usar a segunda opção e acompanhar o total acumulado usando o RowDataBound manipulador de eventos.

Crie um manipulador de RowDataBound eventos para o GridView selecionando o GridView no Designer, clicando no ícone de raio na janela Propriedades e clicando duas vezes no RowDataBound evento. Isso criará um novo manipulador de eventos nomeado 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 manipulador de RowDataBound 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. Uma vez que isso tenha sido estabelecido, a Northwind.ProductsRow instância que acabou de ser vinculada ao GridViewRow objeto em e.Row é 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 ). Acompanhamos o total acumulado UnitPrice e o número de não-registrosNULL UnitPrice porque 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 manipulador de RowDataBound 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 foram adicionadas, podemos ter certeza de que, quando estivermos prontos para exibir os dados de resumo no rodapé, os cálculos de total acumulado terão sido concluídos. A última etapa, então, é definir esses valores nas células do rodapé.

Para exibir texto em uma célula de rodapé específica, use e.Row.Cells[index].Text = value, onde 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 foi adicionado. Observe como o faz ToString("c") com que as informações de resumo do 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 de fundo avermelhada (clique para exibir a imagem em tamanho real)

Resumo

A exibição de 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 do GridView ShowFooter é definida como true e pode ter o texto em suas células definido programaticamente por meio do manipulador de RowDataBound eventos. O cálculo dos dados de resumo pode ser feito consultando novamente o banco de dados ou usando o código na classe code-behind da página de 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.

Boa programação!

Sobre o autor

Scott Mitchell, autor de sete livros ASP/ASP.NET e fundador da 4GuysFromRolla.com, trabalha com tecnologias da Web da Microsoft desde 1998. Scott trabalha como consultor, instrutor e escritor independente. 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.