domingo, 8 de abril de 2012

ASP .NET- Usando GridView (C#) para iniciantes

ASP .NET- Usando GridView (C#) para iniciantes



Este artigo é uma revisão sobre os conceitos básicos sobre a utilização do controle GridView em uma aplicação ASP .NET Web Forms usando a linguagem C#.

Abra o Visual Web Developer 2010 Express Edition e crie um novo web site no menu File-> New Web Site usando o template ASP .NET Web Site e a linguagem C# com o nome GridView_Basico;


Usando este template já temos uma estrutura criada contendo uma maste page e os web forms Default.aspx e About.aspx bem como uma pasta Account contendo páginas para login, registro e alteração de senha de usuário;


Eu vou fazer alguns ajustes na master page apenas para mudar o visual da página e vou alterar a página Default.aspx incluindo um controle GridView na mesma conforme o leiaute abaixo:


Nosso objetivo será realizar a manutenção das informações da tabela Cliente do banco de dados Cadastro.mdf do SQL Server.

Obs: Este banco de dados foi criado no SQL Server Management Studio

A tabela Cliente possui a seguinte estrutura:


Precisamos então exibir as informações no controle GridView e permitir que as informações da tabela seja editadas e excluídas.

Vamos implementar essas funcionalidades usando apenas o controle GridView e os seus eventos.

Vejamos então um resumos dos principais propriedades e eventos envolvidos neste processo:

Propriedades:

AutoGenerateColumns Esta propriedade só aceita um valor booleano. O valor padrão é true. Quando definido como False significa
que os objetos BoundField não são criados automaticamente e que vamos criar os campos manualmente.
DataKeyNames: Esta propriedade é usada para associar um valor com cada linha do GridView. Podemos atribuir o nome de
uma única ou mais de uma coluna do banco de dados. Quando atribuir mais de uma coluna separe-as por uma
vírgula. Ela representa valores DataKey e dessa froma identificam exclusivamente registros em linhas GridView.
<Columns> É uma coleção de colunas que o GridView contém. Podemos usá-la para controlar a exibição das colunas.
<asp:TemplateField> É usado para adicionar controles ASP.Net em linhas GridView. Um TemplateField representa uma coluna no GridView.
Ele personaliza a aparência da interface do usuário no GridView. É útil quando estamos utilizando um GridView para
editar um registro de banco de dados.
<ItemTemplate> Especifica o conteúdo que é exibido em um objeto TemplateField. Ele exibe um layout para o TemplateField.
<EditItemTemplate> Também especifica os índices que são exibidos em um TemplateField mas em no modo EditMode.
Eval É um método que é usado para exibir dados. Neste método, passamos um nome de um campo do banco de dados como um argumento.
<asp:CommandField> É um campo especial que exibe botões de comando para executar selecionar, editar, inserir e excluir.

Eventos:

onrowcancelingedit Dispara o evento rowcancelingedit. Este evento é disparado quando o botão Cancel da linha no modo Edit é clicado.
onrowediting Dispara o evento RowEditing. Este evento é disparado quando o botão Edit da linha é clicado
onrowdeleting
Dispara o evento RowDeleting. Este evento é disparado quando o botão Delete da linha é clicado
onrowupdating
Dispara o evento RowUpdating. Este evento é disparado quando o botão Update da linha é clicado

Vamos criar uma pasta no projeto clicando com o botão direito do mouse sobre o nome do projeto e selecionando a opção New Folder e informando o nome Imagem;

A seguir vamos incluir nesta pasta as imagens : aceitar.jpg, editar.jpg e erro.jpg que iremos usar em nossa aplicação.

Configurando o GridView

Com base nesses recursos e usando os eventos e propriedades descritos vamos configurar o controle GridView de forma a exibir os registros e permitir sua manutenção.

Vamos então definir para o controle GridView estas propriedades e eventos conforme o código abaixo:

    <asp:GridView ID="ClienteGridView" runat="server" AutoGenerateColumns="False"
    DataKeyNames="id" 
    onrowcancelingedit="EmployeeGridView_RowCancelingEdit" 
    onrowediting="EmployeeGridView_RowEditing"             
    onrowdeleting="EmployeeGridView_RowDeleting" 
    onrowupdating="EmployeeGridView_RowUpdating">
       
    <Columns>
    <asp:TemplateField HeaderText="Cod.">
    <ItemTemplate>    <%#Container.DataItemIndex+1 %>    </ItemTemplate>
    </asp:TemplateField>
    <asp:TemplateField HeaderText="Nome">
    <ItemTemplate>    <%#Eval("nome") %>    </ItemTemplate>
    <EditItemTemplate>
    <asp:TextBox ID="txtnome" runat="server" Text='<%#Eval("nome") %>'></asp:TextBox>
    </EditItemTemplate>
    </asp:TemplateField>    
     <asp:TemplateField HeaderText="Endereco">
    <ItemTemplate>    <%#Eval("endereco") %>    </ItemTemplate>
    <EditItemTemplate>
    <asp:TextBox ID="txtendereco" runat="server" Text='<%#Eval("endereco") %>'></asp:TextBox>
    </EditItemTemplate>
    </asp:TemplateField>
     <asp:TemplateField HeaderText="Email">
    <ItemTemplate>    <%#Eval("email") %>    </ItemTemplate>
    <EditItemTemplate>
    <asp:TextBox ID="txtemail" runat="server" Text='<%#Eval("email") %>'></asp:TextBox>
    </EditItemTemplate>
    </asp:TemplateField>
    <asp:CommandField ShowEditButton="true" ButtonType ="Image" 
        EditImageUrl="Imagem/editar.jpg" 
        UpdateImageUrl="Imagem/aceitar.jpg"
        CancelImageUrl="Imagem/erro.jpg" HeaderText="Editar" />
    <asp:CommandField ShowDeleteButton="true" ButtonType="Image" DeleteImageUrl="Imagem/erro.jpg" HeaderText="Deletar" />  
    </Columns>
    </asp:GridView>

Observe que na propriedade DataKeyNames definimos o campo id e os campos nome,endereco e email foram definidos como ItemTemplates.Através desta propriedade, podemos pode obter ou definir a(s) coluna(s) que representa(m) a Chave Primária dos registros exibidos no GridView.

As imagens foram usadas na propriedade CommandField onde usamos um Button do tipo Image e definimos dois botões : um para editar e outro para deletar.

A aparência do controle ficou assim:


Definindo o código da aplicação

Falta agora definir o código da aplicação para acessar o banco de dados e realizar as operações para consultar, editar e excluir informações da tabela Cliente.

Vamos criar 3 stored procedures no banco de dados Cadastro para realizar estas operações. Podemos fazer isso diretamente na janela DataBase Explorer:

Vamos iniciar criando a stored procedure para selecionar informações do cliente:


Repetindo a operação acima vamos criar as stored procedures para:

1- Atualizar Cliente - sproc_AtualizaCliente

CREATE PROCEDURE sproc_AtualizaCliente
(
@id int,
@nome varchar(50),
@endereco varchar(50),
@email varchar(70)
)
AS
update Cliente set nome=nome,
endereco=@endereco,
email=@email
where id=@id


2- Deletar Cliente - sproc_DeletaCliente

CREATE PROCEDURE sproc_DeletaCliente
(
@id int
)
AS
Delete from cliente where id = @id


A final veremos as stored procedures criadas conforme mostra a figura a seguir:


Vamos agora definir o código no arquivo code-behind Default.aspx.cs;

Declare os namespaces:

using System;
using System.Web.UI;
using System.Web.UI.WebControls;
using System.Data;
using System.Data.SqlClient;


Defina a variável para a string de conexão:

string strConexao = null;

No evento Load da página Default.aspx digite o código :

protected void Page_Load(object sender, EventArgs e)
{
strConexao = @"Data Source=.\SQLEXPRESS;Initial Catalog=Cadastro;Integrated Security=SSPI;";
//chama apenas na primeira carga da pagina
if (!Page.IsPostBack)
{
preencheGrid();
}
}

Definimos a string de conexão com o banco de dados Cadastro e chamamos a rotina preencheGrid();

A seguir digite o código da rotina preencheGrid() conforme abaixo:

public void preencheGrid()
{
//cria uma conexão usando a string de conexão definida
SqlConnection con = new SqlConnection(strConexao);
//abre a conexão
con.Open();
//define um objeto Command que usa a stored procedure na conexão criada
SqlCommand cmd = new SqlCommand("sproc_GetClientes", con);
//realizar um acesso somente-leitura no banco de dados
SqlDataReader dr = cmd.ExecuteReader();
//cria um datatable que conterá os dados
DataTable dt = new DataTable();
//carrega o datatable com os dados do datareader
dt.Load(dr);
//exibe os dados no GridView
ClienteGridView.DataSource = dt;
ClienteGridView.DataBind();
}

Executando o projeto neste momento iremos obter: (Para poder executar o projeto neste momento comente as linhas com os eventos do gridview)


Neste momento não temos ainda as funcionalidades para editar e excluir dados prontas então vamos a elas...

Podemos visualizar os eventos do controle GridView selecionando o controle e na janela de propriedades clicar no ícone para exibir os eventos:


Para editar dados no GridView usamos 3 eventos:

1- RowCancelingEdit: Este evento é disparado quando cancelamos a atualização de um registro, o que significa que usamos isso quando estamos em modo de edição de um GridView e queremos retornar o GridView de volta ao modo de visualização, sem qualquer atualização.

Vamos definir o seguinte código no evento RowCancelingEdit:

protected void ClienteGridView_RowCancelingEdit(object sender, System.Web.UI.WebControls.GridViewCancelEditEventArgs e)
{
ClienteGridView.EditIndex = -1;
preencheGrid();
}

A propriedade EditIndex de um GridView determina o índice de uma linha em modo de edição. EditIndex =- 1 significa que nenhuma linha esta no modo de edição.

2- RowEditing: Este evento é usado para alterar o modo de GridView. Ele é gerado quando o botão de uma linha de edição é clicado, mas antes do GridView entrar em modo de edição.

Defina o código a seguir no evento RowEditing:

protected void ClienteGridView_RowEditing(object sender, System.Web.UI.WebControls.GridViewEditEventArgs e)
{
ClienteGridView.EditIndex = e.NewEditIndex;
preencheGrid();
}

e.NewEditIndex determina qual linha foi clicada e qual estará no modo de edição.

3- RowUpdating: É disparado antes de um GridView atualizar um registro, o que significa que o botão da linha atualização foi clicado, mas antes do GridView atualizar a linha.

Inclua o seguinte código neste evento:

protected void ClienteGridView_RowUpdating(object sender, System.Web.UI.WebControls.GridViewUpdateEventArgs e)
{
//Obtem cada valor único do DataKeyNames
int id = Convert.ToInt32(ClienteGridView.DataKeys[e.RowIndex].Value.ToString());
//Obtem o valor do TextBox no EditItemTemplet da linha clicada
string nome = ((TextBox)ClienteGridView.Rows[e.RowIndex].FindControl("txtnome")).Text;
string endereco = ((TextBox)ClienteGridView.Rows[e.RowIndex].FindControl("txtendereco")).Text;
string email = ((TextBox)ClienteGridView.Rows[e.RowIndex].FindControl("txtemail")).Text;
//abre a conexão
SqlConnection con = new SqlConnection(strConexao);
con.Open();
//Utiliza a stored procedure sproc_AtualizaCliente na conexão
SqlCommand cmd = new SqlCommand("sproc_AtualizaCliente", con);
//define o tipo de comando
cmd.CommandType = CommandType.StoredProcedure;
//passa os parâmetros para a stored procedure
cmd.Parameters.AddWithValue("@id ", id);
cmd.Parameters.AddWithValue("@nome ", nome);
cmd.Parameters.AddWithValue("@endereco ", endereco);
cmd.Parameters.AddWithValue("@email ", email);
//Método que retorna as linhas afetadas
cmd.ExecuteNonQuery();
//nenhuma linha no modo de edição
ClienteGridView.EditIndex = -1;
//preenche o grid nomvanete
preencheGrid();
}

Executando o projeto e a seguir clicando no ícone para editar um registro teremos:


Vamos alterar um valor e clicar no botão para aceitar a alteração:


Vamos agora definir a funcionalidade para excluir um registro da tabela.

Aqui usamos o evento RowDeleting.

Este evento é gerado quando o botão da linha delete é clicado, mas antes da linha ser excluída.

Defina no evento RowDeleting o código mostrado abaixo:

protected void ClienteGridView_RowDeleting(object sender, GridViewDeleteEventArgs e)
{
int id = Convert.ToInt32(ClienteGridView.DataKeys[e.RowIndex].Value.ToString());
SqlConnection con = new SqlConnection(strConexao);
con.Open();
SqlCommand cmd = new SqlCommand("sproc_DeletaCliente", con);
cmd.CommandType = CommandType.StoredProcedure;
cmd.Parameters.AddWithValue("@id ", id);
cmd.ExecuteNonQuery();
preencheGrid();
}

No código estamos obtendo o valor do código do cliente em DataKeyNames e usando a stored procedure para excluir um registro:

Do jeito que fizemos quando o usuário clicar no botão para excluir um registro não haverá nenhuma solicitação de confirmação ao usuário.

Vamos usar o evento RowDataBound para incluir uma solicitação de mensagem de confirmação de exclusão de registro ao usuário usando código JavaScript;

O evento RowDataBound é disparado sempre que uma linha é adicionada ao GridView, isto ocorre tanto quando o GridView é criado pela primeira vez e sempre que a página é recarregada. Defina o código abaixo neste evento:

protected void ClienteGridView_RowDataBound(object sender, GridViewRowEventArgs e)
{
if (e.Row.RowState == (DataControlRowState.Edit | DataControlRowState.Alternate) | e.Row.RowState == DataControlRowState.Edit)
{
return;
}

if (e.Row.RowType == DataControlRowType.DataRow)
{
//Referencia ao linkbutton delete
ImageButton deleteButton = (ImageButton)e.Row.Cells[5].Controls[0];
deleteButton.OnClientClick ="if (!window.confirm('Confirma a exclusão deste registro ?')) return false;";
}
}

Vamos entender o que fizemos aqui:

Primeiro verificamos se não estamos no modo de edição, pois quando o usuário clicar no botão para editar deveremos retornar sem exibir a mensagem;

Se não estivermos no modo de edição então verificamos se estamos em uma linha do gridview para então exibir a mensagem de solicitação de confirmação.


Dessa forma temos todas as funcionalidades implementadas e prontas apenas usando os recursos do controle GridView.

É claro que o código pode ser melhorado com a inclusão de um tratamento de erros (coisa que eu não fiz) e também com a criação de uma pequena camada de acesso dados. Pequenos detalhes que podem ser fatais se a aplicação fosse um sistema para produção.

Pegue o projeto completo aqui: GridViewBasico.zip



João 7:16 Respondeu-lhes Jesus: A minha doutrina não é minha, mas daquele que me enviou.
João 7:17
Se alguém quiser fazer a vontade de Deus, há de saber se a doutrina é dele, ou se eu falo por mim mesmo.
João 7:18
Quem fala por si mesmo busca a sua própria glória; mas o que busca a glória daquele que o enviou, esse é verdadeiro, e não há nele injustiça.

Referências: