GridView - Acesso a dados com paginação, formatação e sumarização (C#)


Neste artigo eu vou mostrar como realizar algumas tarefas básicas com o componente GridView em uma página ASP .NET usando a linguagem C#.

A classe GridView Exibe os valores de uma fonte de dados em uma tabela onde cada coluna representa um campo e cada linha representa um registro.O Controlador GridView permite a você selecionar, classificar e editar esses itens.

Meu objetivo é :

O detalhe é que eu vou mostrar como realizar estas tarefas sem usar os assistentes; vou fazer tudo usando a linguagem C#.

À primeira vista são tarefas simples mas que podem dar uma grande dor de cabeça para os iniciantes.

Eu vou usar como ferramenta neste artigo o Visual Web Developer 2008 Express Edition que é grátis e o banco de dados Northwind.mdb que vou colocar na pasta c:\dados na minha máquina local. (Você pode alterar a localização desde que altere também a string de conexão usada no projeto)

1- Criando o web site no Visual Web Developer 2008 Express (VWD)

Abra o seu VWD e no menu  File->New Web Site selecione o template ASP .NET Web Application, selecione o location File System e informe a pasta onde deverá ser criado o web site.(No meu caso c:\aspn) e informe o nome GridViewAcessoDados. Selecione também a linguagem Visual C# (note que você pode escolher também VB .NET);

Na página Default.aspx inclua a partir da ToolBox um controle GridView  (ID=gdvProdutos) e um controle Button (ID=btnAcessoDados), conforme o leiaute abaixo:

Selecione o componente GridView e na janela de propriedades define as seguintes propriedades do controle:
  • AllowPaging = True
  • PageSize = 10
  • ShowFooter = True

Selecione o controle Button e defina a sua propriedade Text como sendo: "Acessar dados MsAccess"

1- Acessando o banco de dados Northwind.mdb na pasta c:\dados

Quando o web site for carregados podemos acessar os dados diretamente ou podemos também exibir a página com o botão de comando solicitando a intervenção do cliente para que os dados sejam exibidos. Eu vou usar esta última abordagem.

Ao ser carregada a página Default.aspx irá exibir o botão de comando - Acessar dados MsAccess; quando o usuário clicar neste botão iremos fazer o acesso aos dados exibindo-os no GridView.

Para que isso ocorra eu vou colocar no evento Click do botão de comando (btnAcessoDados) o código abaixo:

  protected void btnAcessoDados_Click(object sender, EventArgs e)
  {
         populagrid();
  }

A rotina populagrid() deverá realizar o acesso e a exibição dos dados.

Antes de mostrar o seu código temos que definir a string de conexão com o banco de dados Northwind.mdb. Eu vou usar o arquivo web.config para armazenar a string de conexão. Fazemos isso definindo a tag <connectionStrings> conforme abaixo:

.....
<connectionStrings>
    <add name="OleDbConnectionString" connectionString="Provider=Microsoft.Jet.OLEDB.4.0;Data Source=c:\dados\Northwind.mdb;User Id=admin;Password=;"/>
</connectionStrings>
.....

Aqui temos :

Antes de definir o código você deve declarar no início do formulário web a utilização dos namespaces Data.OleDb e Configuration:

using System.Configuration;
using
System.Data.OleDb;

Agora já podemos definir a rotina populagrid() conforme o código a seguir:

    private void populagrid()
    {
        //obtem a string de conexão do arquivo web.config
        string strConnectionString = ConfigurationManager.ConnectionStrings["OleDbConnectionString"].ConnectionString;
        //cria uma instância do objeto Connection
        OleDbConnection mConnection = new OleDbConnection(strConnectionString);
        // cria um objeto Command
        string strCommandText = "SELECT ProductID, ProductName,UnitPrice From Products";
        // abre a conexão com o banco de dados
        mConnection.Open();
       //cria um objeto DataAdapter e define o comando que será usado
        OleDbDataAdapter da = new OleDbDataAdapter();
        da.SelectCommand = new OleDbCommand(strCommandText, mConnection);
        //cria um DataTable
        DataTable dt = new DataTable();
        da.Fill(dt);

        // exibe os dados e fecha a conexão
        gdvProdutos.DataSource = dt;
        gdvProdutos.DataBind();

        //fecha a conexão 
        mConnection.Close();
    }

Obs: Uma boa prática seria criar uma camada de acesso a dados separada da camada de interface mas por questão de simplicidade eu vou criar o acesso a dados diretamente no formulário.

Neste código estou  usando ADO .NET para efetuar a conexão, onde a string de conexão esta sendo obtida do arquivo web.config pela classe ConfigurationManager(): ConfigurationManager.ConnectionStrings["OleDbConnectionString"].ConnectionString;

Criamos a conexão usando o objeto OleDbConnection() e definimos o comando usando a instrução SQL :
"SELECT ProductID, ProductName,UnitPrice From Products";

que irá selecionar o código, o nome e preço unitário da tabela Products;

Criamos um DataTable pois este objeto dá suporte a paginação (se você usar um DataReader não vai conseguir paginar) e preenchemos o DataTable com o resultado da execução do comando via DataAdapter da.Fill(dt);

Depois é só atribuir o DataTable gerado ao DataSource e usar o binding do controle para exibir os dados na página:

 gdvProdutos.DataSource = dt;
 gdvProdutos.DataBind();

Se você rodar o projeto agora e tentar paginar não vai conseguir. Teremos que usar o evento PageIndexChanging() para controlar a paginação.

O evento PageIndexChanging ocorre quando um dos botões da página for clicado, mas antes do GridView manipular a operação de paginação.

Isso permite que você forneça um método de Manipulação de evento que executa uma rotina personalizada, como cancelar a operação de paginação, sempre que esse evento ocorrer.

Um objeto GridViewPageEventArgs é passado para o método de manipulação de evento, que permite a você determinar o índice da página Selecionada pelo usuário e para indicar que a operação de paginação deve ser cancelada. Para cancelar a operação de paginação, defina a propriedade de Cancel do objeto GridViewPageEventArgs como true

Para que a paginação funcione devemos definir no evento PageIndexChanging o seguinte código:

protected void gdvProdutos_PageIndexChanging(object sender, GridViewPageEventArgs e)
{
        gdvProdutos.PageIndex = e.NewPageIndex;
        populagrid();
}

Neste código estamos definindo o novo índice da página e chamando novamente a rotina populagrid();

Executando o projeto e após clicar no botão Acessar Dados MsAccess iremos obter a seguinte página:

Precisamos agora efetuar as seguintes alterações:

Então vamos ao trabalho:

1- Formatando o cabeçalho

Devemos efetuar a formatação do cabeçalho antes de realizar a vinculação dos dados ou seja antes de chamar a rotina populagrid() vamos alterar o código do evento Click do botão de comando que deverá ficar assim:

  protected void btnAcessoDados_Click(object sender, EventArgs e)
    {
        //define que as colunas não serão geradas automaticamente
        gdvProdutos.AutoGenerateColumns = false;

        //define e realiza a formatação de cada coluna
        BoundField coluna1 = new BoundField();
        coluna1.DataField = "ProductID";
        coluna1.HeaderText = "Código";
        gdvProdutos.Columns.Add(coluna1);
        BoundField coluna2 = new BoundField();
        coluna2.DataField = "ProductName";
        coluna2.HeaderText = "Produto";
        gdvProdutos.Columns.Add(coluna2);
        BoundField coluna3 = new BoundField();
        coluna3.DataField = "UnitPrice";
        coluna3.HeaderText = "Preço Unitário";
        coluna3.HtmlEncode = false;
        gdvProdutos.Columns.Add(coluna3);

        populagrid();
    }

Neste código estamos criando as colunas e definindo a formatação do texto que desejamos exibir para cada coluna. Onde temos:

Executando o projeto novamente obtemos a página exibindo os textos desejados no cabeçalho:

2- Mudando a cor de uma linha com base em uma condição

Agora vamos mudar a cor da linha do produto Chai e do produto Ikura. Para fazer isso usamos o evento RowDataBound pois teremos que fazer uma verificação na linha no momento em que ela for vinculada ao GridView.

O evento RowDataBound() é usado com frequência para alterar diversas características das linhas do controle GridView.

O evento RowDataBound ocorre quando uma linha de dados é vinculada a dados em um Controle de GridView.

Antes do Controle GridView pode ser processado, cada linha no Controle deve ser ligada a um registro no Origem de Dados.O evento RowDataBound é disparado quando uma linha de dados (representada por um objeto GridViewRow ) é Ligado aos dados no Controle GridView.Isso permite que você fornecer um método de Manipulação de evento que executa uma rotina Personalizar, como modificar os valores dos dados Ligados a linha, sempre que esse evento ocorre.

Um objeto GridViewRowEventArgs é passado para o evento-Manipulação do método, que permite a você acessar as propriedades da linha sendo Ligados.Para acessar uma célula específica na linha, use a propriedade Cells do objeto GridViewRow contido a propriedade Row do objeto GridViewRowEventArgs.Você pode determinar que tipo de linha (linha de cabeçalho, linha de dados e assim por diante) que está sendo Ligado usando a propriedade RowType.

Vamos então incluir o código abaixo no evento RowDataBound():

protected void gdvProdutos_RowDataBound(object sender, GridViewRowEventArgs e)
    {
        //colorindo uma linha com base no conteúdo de uma célula
        if (e.Row.RowType == DataControlRowType.DataRow)
        {
            switch (e.Row.Cells[1].Text)
            {
                case "Chai":
                    e.Row.BackColor = System.Drawing.Color.Yellow;
                    break;
                case "Ikura":
                    e.Row.BackColor = System.Drawing.Color.Crimson;
                    break;
            }
        }     
    }

Veja o que fizemos neste código:

1- Verificamos o tipo de linha que esta sendo vinculada aos dados e se for uma linha de dados(DataRow) :

      if (e.Row.RowType == DataControlRowType.DataRow)

2- Verificamos se o texto da célula(Cells) é igual a Chai ou Ikura e em caso positivo mudamos a cor de fundo da linha (System.Drawing.Color.Yellow):

         switch (e.Row.Cells[1].Text)
            {
                case "Chai":
                    e.Row.BackColor = System.Drawing.Color.Yellow;
                    break;
                case "Ikura":
                    e.Row.BackColor = System.Drawing.Color.Crimson;
                    break;
            }

Executando o projeto novamente obtemos:

Obs: Ao usar o evento RowDataBound () verifique sempre o tipo da linha através de e.row.rowtype. Em alguns casos teremos também que verificar o RowState.

3- Aplicando um efeito zebrado ao GridView

Para aplicar o efeito zebrado com linhas alternadas de cores distintas usamos também o efeito RowDataBound.

Vamos incluir o código , que esta destacado em azul, no evento:

  protected void gdvProdutos_RowDataBound(object sender, GridViewRowEventArgs e)
    {
        //da um efeito zebrado ao grid colorindo linhas alternadamente 
        if (e.Row.RowType == DataControlRowType.DataRow)
        {
            if (((e.Row.RowIndex + 1) % 2) == 0)
            {
                e.Row.BackColor = System.Drawing.Color.LightSkyBlue;
            }
        }
        //colorindo uma linha com base no conteúdo de uma célula
        if (e.Row.RowType == DataControlRowType.DataRow)
        {
            switch (e.Row.Cells[1].Text)
            {
                case "Chai":
                    e.Row.BackColor = System.Drawing.Color.Yellow;
                    break;
                case "Ikura":
                    e.Row.BackColor = System.Drawing.Color.Crimson;
                    break;
            }
        }     
    }

Aqui primeiro verificamos se temos uma linha de dado e depois definimos uma condição para alterar cor de fundo da linha

Executando o projeto teremos a página exibindo o controle GridView() com efeito zebrado:

4- Totalizando os valores da coluna Preço Unitário

Para terminar vamos totalizar os valores da coluna Preço Unitário por página.

Para guardar o valor total por página precisamos criar uma variável chamada valorTotal que seja visível no projeto. Vamos definir então a variável no início do formulário:

private double valorTotal = 0;

Iremos exibir o valor total por página no rodapé (footer). Foi por isso que definimos no início a propriedade ShowFooter do GridView como True:

Novamente vamos usar o evento RowDataBound incluindo o seguinte trecho de código:

     //calculando o total de uma coluna por página
        if (e.Row.RowType == DataControlRowType.DataRow)
        {
            CalculaTotal(e.Row.Cells[2].Text);
            e.Row.Cells[2].Text = string.Format("{0:c}", Convert.ToDouble(e.Row.Cells[2].Text));
            e.Row.Cells[2].HorizontalAlign = HorizontalAlign.Right;
        }
        else if (e.Row.RowType == DataControlRowType.Footer)
        {
            e.Row.Cells[1].Text = "Total";
            e.Row.Cells[2].Text = string.Format("{0:c}", valorTotal);
            e.Row.Cells[2].HorizontalAlign = HorizontalAlign.Right;
        }

 

Vamos entender o que foi feito :

1- Primeiro verificamos se a linha é uma linha de dados :  if (e.Row.RowType == DataControlRowType.DataRow)

2- Neste caso iremos calcular o total por página de cada linha do GridView da terceira célula da linha:   CalculaTotal(e.Row.Cells[2].Text);

3- Depois formatamos o valor obtido e convertido para o double :  e.Row.Cells[2].Text = string.Format("{0:c}", Convert.ToDouble(e.Row.Cells[2].Text));

4- Aplicamos um alinhamento a direita: e.Row.Cells[2].HorizontalAlign = HorizontalAlign.Right;

Para funcionar temos então que definir a rotina CalculaTotal() que calcula o valor total terceira célula da linha do GridView():

       private void CalculaTotal(string _preco)
        {
            try
            {
                valorTotal += Double.Parse(_preco);
            }
            catch (Exception ex)
            {
                HttpContext.Current.Response.Write(ex.ToString());
            }
        }

Executando o projeto iremos obter a seguinte página:

Só nos resta dizer: Missão cumprida !!

Até a próxima...e pegue o projeto completo aqui: GridViewAcessoDados.zip

Eu sei é apenas ASP .NET, mas eu gosto...

Referências:


José Carlos Macoratti