Formatação Avançada de DataGrid com ItemDataBound

Veja neste artigo, como implementar formatações no DataGrid, simulando agrupamento de valores.

Formatação Avançada de DataGrid com ItemDataBound

 

Estava querendo produzir DataGrids com as mesmas funcionalidades de relatórios impressos e a coisa toda se parecia com alguns sistemas de gerenciamento de informações muito caros que foram substituídos com o .NET. O produto final deveria focar a atenção dos usuários nos dados desejados, sem as complicações de campos extras e outros detalhes. Este artigo se propõe a introduzir o uso de alguns truques simples para incrementar a aparência dos DataGrids.

Veremos então como fazer para:

·        Criar agrupamentos de colunas

·        Realçar subtotais e totais gerais

·        Realçar células individuais com base em valores de dados

 

Dados SQL e Banco de dados

Foram usados o Northwind e o SQL Server DB para produzir os dados para este artigo, com um subtotal para cada categoria de produto e um total geral no final. O código funcionará para qualquer fonte de dados. As stored procedures SQL foram também incluídas para aqueles que estejam interessados em recriar exatamente o que é mostrado aqui.

 

Quase toda a lógica de negócio foi colocada no lado do banco de dados, usando o DataGrid apenas para fins de exibição, portanto, toda a ordenação e os totais são feitos aqui.

 

CREATE PROCEDURE usp_sales_by_cate AS

 

create table #temp ( Sorty int, CategoryName varchar(50),

         ProductName varchar(50), ProductSales real)

 

-- Get Base Sales

INSERT INTO #temp

SELECT 0, dbo.Categories.CategoryName, dbo.Products.ProductName,

SUM(dbo.[Order Details Extended].ExtendedPrice)

AS ProductSales

FROM dbo.Categories INNER JOIN

dbo.Products INNER JOIN

dbo.Orders INNER JOIN

dbo.[Order Details Extended] ON dbo.Orders.OrderID =

       dbo.[Order Details Extended].OrderID ON

dbo.Products.ProductID =

 dbo.[Order Details Extended].ProductID ON dbo.Categories.CategoryID =

                  dbo.Products.CategoryID

WHERE (dbo.Orders.OrderDate BETWEEN '19970101' e '19971231')

GROUP BY dbo.Categories.CategoryName, dbo.Products.ProductName

ORDER BY dbo.Categories.CategoryName

 

-- Build SubTotal

INSERT INTO #temp

SELECT 1 , CategoryName, 'SubTotal', sum( ProductSales)

from #temp

 

group by CategoryName

-- Build Grand Total

INSERT INTO #temp

SELECT 2 , 'XXXXX', 'Grand Total', sum( ProductSales)

from #temp

Where sorty = 0

 

-- Display Values

SELECT CategoryName, ProductName, ProductSales from #temp

order by CategoryName, Sorty

 

Criando Agrupamentos

Não queremos que as categorias sejam exibidas sempre na primeira coluna, porém apenas quando mudarem, o que dará um aspecto limpo e agradável ao DataGrid, permitindo aos usuários achar os itens rápida e facilmente.

Primeiro, criamos uma variável pública que funcionará para a página inteira e, o mais importantemente, lembrará algo a cada vez que o <ITEMDATABOUND> rodar para cada linha do DataGrid. O Page Load, será também pré-configurado (ocorreram algumas situações estranhas em que isto não aconteceu).

 

public class WebForm1 : System.Web.UI.Page

{

 public string LastColumn;

..

..

 

private void Page_Load(object sender, System.EventArgs e)

{

// Configurar LastColumn para branco

if (!IsPostBack) LastColumn = "";

 

A seguir, usamos a variável <LASTCOLUMN> para localizar as alterações nos dados que irão para o DataGrid. Se o valor da célula de cell[0] não for alterado, o texto da mesma será apagado e a borda será removida:

 

e.Item.Cells[0].Style.Add("BORDER", "none").

 

Para ignorar o cabeçalho (header) do DataGrid:

 

if( ( e.Item.ItemType.ToString()!= "Header"))

    {.....

 

Isto também pode ser utilizado para os itens, itens alternativos e rodapés (footers) em um DataGrid, para especializar o código.

 

A seguir, o código completo para agrupar a primeira coluna do DataGrid:

 

private void DataGrid1_ItemDataBound(object sender,

    System.Web.UI.WebControls.DataGridItemEventArgs e)

{

     //Obter o texto da coluna 0 atual

      string CurrentColumn = e.Item.Cells[0].Text;

 

   // Pular Headers

   if( ( e.Item.ItemType.ToString()!= "Header"))

    {

      // Houve alguma alteração

      if (CurrentColumn == LastColumn)

       {

        // Sem alteração na Coluna 0

        //limpar e remover a borda

        e.Item.Cells[0].Text = "";

        e.Item.Cells[0].Style.Add("BORDER", "none");

       }

      else

        {

         // esta eh a primeira da serie

         // atribuir LastColumn para a coluna atual

         LastColumn = CurrentColumn;

        // Adicionar uma cor de fundo para Cell[0]

        e.Item.Cells[0].BackColor =

               System.Drawing.Color.WhiteSmoke;

        }

}

 

Realçando Subtotais e Totais Gerais

 

Isto é bastante simples, caso o texto da célula for "Sub Total" / "Grand Total", então configuramos a fonte, o tipo, as cores, etc.

 

// Verificar se eh um SubTotal

string MyCol2 = e.Item.Cells[1].Text;

 

if (MyCol2 == "SubTotal")

 {

  e.Item.Font.Bold = true;

  e.Item.BackColor = Color.DimGray;

  e.Item.ForeColor = Color.White;

 

  // limpar Column 0

  e.Item.Cells[0].Text = "";

  e.Item.Cells[0].Style.Add("BORDER", "none");

  e.Item.Cells[0].BackColor = Color.Transparent;

 }

 

if (MyCol2 == "Grand Total")

  {

   e.Item.Font.Bold = true;

   e.Item.BackColor = Color.Red;

   e.Item.ForeColor = Color.White;

   e.Item.Cells[0].Style.Add("BORDER", "none");

   e.Item.Cells[0].BackColor = Color.Transparent;

}

 

Realçando Células Individuais

 

Este recurso é amplamente utilizado para exibir valores negativos em vermelho (do modo como se faz em contabilidade). Descobrimos que a conversão de string para número, pode produzir alguns erros estranhos, por isso, geralmente envelopamos as conversões em um try/catch para ignorar qualquer erro que possa surgir.

 

//  Destacar itens caso as vendas estejam abaixo de 5000

string MyStr = e.Item.Cells[2].Text;

 

try

{

  double MyValue = double.Parse(MyStr);

  

  if (MyValue < 5000 )

  {

    e.Item.Cells[2].ForeColor = Color.Red;

    e.Item.Cells[2].Font.Bold = true;

  }

}

catch(Exception)

{

 // numero invalido

}

 

 

Ebook exclusivo
Dê um upgrade no início da sua jornada. Crie sua conta grátis e baixe o e-book

Artigos relacionados