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:
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;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:
http://msdn.microsoft.com/pt-br/library/system.web.ui.webcontrols.gridview.aspx
http://msdn.microsoft.com/pt-br/library/system.web.ui.webcontrols.gridview.rowdatabound.aspx
http://msdn.microsoft.com/pt-br/library/system.web.ui.webcontrols.gridview.pageindexchanging.aspx