ASP.NET 2.0  - Realizando a manutenção de dados com o controle Repeater


E lá vamos nós voltar a abordar o controle Repeater desta vez para mostrar como realizar as operações de Inclusão, alteração e exclusão no controle em uma aplicação ASP .NET usando o Visual Web Developer 2010 Express Edition.

Embora este controle tenha tido a grande parte de suas funcionalidades absorvidas pelos novos controles GridView, DetailsView, e FormView na ASP.NET 2.0 vou apresentar o controle presente na nova versão por questões de compatibilidade.

O controle Repeater é identificado pela tag <asp:Repeater></asp:Repeater>, e exibe uma lista repetidas de itens a ele vinculados podendo ser usado para exibir registros de fonte de dados diversas.  O controle esta baseado na utilização de templates que são modelos para exibição de saída usando expressões de vinculação , controles de servidor e tags XHTML que estruturam a exibição dos dados. A sub tag <ItemTemplate> é usada no interior da tag do controle com o bloco de código para renderizar os itens de dados que serão exibidos no controle.

Então vamos a prática...

Antes de criarmos o projeto vamos definir o banco de dados que iremos usar no exemplo. Será algo bem simples.

Abaixo temos a estrutura da tabela Lista do banco de dados Escola.mdf criado no SQL Server 2008 Express:

Vamos tratar apenas os campos id, nome e curso e usando o controle Repeater.

Abra o Visual Web Developer 2010 Express e no menu File selecione New Web Site;

A seguir selecione o template ASP .NET Empty Web Site, usando a linguagem Visual Basic, e informe o nome RepeaterCRUD e clique em OK;

Vamos incluir um WebForm no projeto. No menu WebSite selecione Add New Item e a seguir selecione o template Web Form aceitando o nome Default.aspx e clicando em Add;

A string de conexão do banco de dados esta presente no arquivo Web.Config e esta assim definida:

 <appSettings>
    <add key="ConnectionString" value="Data Source=.\SQLEXPRESS;Initial Catalog=Escola;Integrated Security=True"/>
  </appSettings>

Vamos definir a interface usando o controle Repeater na página Default.aspx conforme o leiaute exibido a seguir:

Estamos usando os seguintes controles nesta página:

O código fonte da página é dada a seguir deve ser colocado entre as tags <div> da página Default.aspx:

  <asp:Repeater ID="cpRepeater" runat="server" onitemcommand="cpRepeater_ItemCommand" 
            onitemdatabound="cpRepeater_ItemDataBound">
        <HeaderTemplate>
        <table width="500px" border="1px">
        <tr style="background-color:#99CCFF">
        <td >Email</td>
        <td >Aluno</td>
        <td >Curso</td>
        <td >Opções</td>
        </tr>
        </HeaderTemplate>
        
        <ItemTemplate>
        <tr style="background-color:#ffffff">
        <td >
         <asp:CheckBox ID="chkDeletar" runat="server" />
        </td>
        <td >
            <asp:Label ID="lblid" Visible="false" runat="server" Text='<%# DataBinder.Eval(Container.DataItem, "id") %>'></asp:Label>
            <asp:Label ID="lblNome" runat="server" Text='<%# DataBinder.Eval(Container.DataItem, "nome")%>'></asp:Label>
            <asp:TextBox ID="txtNome" BackColor="#d4d0c8" runat="server" Text='<%# DataBinder.Eval(Container.DataItem, "nome")%>' Visible="false"></asp:TextBox>
         </td>
         <td>
            <asp:DropDownList ID="ddlCurso" runat="server">
            </asp:DropDownList>
         </td>
         <td >
            <asp:LinkButton ID="lnkEditar" runat="server" CommandName="edit" CommandArgument='<%# DataBinder.Eval(Container.DataItem, "id") %>'>Editar</asp:LinkButton>
            <asp:LinkButton Visible="false" ID="lnkAtualizar" runat="server" CommandName="update" CommandArgument='<%# DataBinder.Eval(Container.DataItem, "id") %>'>Atualizar</asp:LinkButton>
            <asp:LinkButton Visible="false" ID="lnkCancelar" runat="server" CommandName="cancel" CommandArgument='<%# DataBinder.Eval(Container.DataItem, "id") %>'>Cancelar</asp:LinkButton>
            <asp:LinkButton ID="lnkDeletar" runat="server" CommandName="delete" OnClientClick='javascript:return confirm("Confirma a exclusão deste registro ?")' 
            CommandArgument='<%# DataBinder.Eval(Container.DataItem, "id") %>'>Deletar</asp:LinkButton>
        </td>
        </tr>
        </ItemTemplate>
        <FooterTemplate>
           <tr style="background-color:#15880a">
           <td colspan="5">
        </FooterTemplate>
        </asp:Repeater>
        <asp:LinkButton ID="lnkDelSelecionado" ForeColor="White" runat="server" onclick="LinkButton1_Click" 
OnClientClick='javascript:return confirm("Confirma exclusão do registro selecionado?")'>Deletar Selecionado</asp:LinkButton>

Observe que estamos usando os templates: HeaderTemplate, ItemTemplate e FooterTemplate.

Estamos usando também JavaScript para solicitar a confirmação da exclusão do registro usando o evento OnClientClick:

OnClientClick='javascript:return confirm("Confirma a exclusão deste registro ?")'

Agora vamos ao código da aplicação que será colocado no arquivo code-behind Default.aspx.vb:

Vamos começar definindo os namespaces usados no código:

Imports System.Data
Imports System.Data.SqlClient
Imports System.Web.UI
Imports System.Web.UI.WebControls


Para exibir os registros na página vamos colocar no evento Load da página a chamada da rotina VincularRepeater() que após verificar se não é um postback irá acessar a tabela Lista e vincular os registros ao controle cpRepeater:

 Protected Sub Page_Load(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Load
        If Not IsPostBack Then
            VinculaRepeater()
        End If
    End Sub

O código da rotina VinculaRepeater() é dado abaixo onde ela obtém a string de conexão do arquivo de configuração e cria um dataset com os dados da tabela Lista;

 Private Sub VinculaRepeater()
        Dim SqlCnn As New SqlConnection(ConfigurationManager.AppSettings("ConnectionString"))
        Dim SqlCmd As New SqlCommand("select * from Lista", SqlCnn)
        Dim Sqlda As New SqlDataAdapter(SqlCmd)
        Dim ds As New DataSet()
        Sqlda.Fill(ds, "Lista")
        cpRepeater.DataSource = ds
        cpRepeater.DataBind()
    End Sub

O evento ItemCommand do controle Repeater corre quando um botão é clicado no controle Repeater e estamos usando o evento para tratar as interações do usuário com os links para editar e deletar registros da página ASP .NET.

Usamos o o método FindControl para pequisar um controle do servidor usando um parâmetro id especificado.

 Protected Sub cpRepeater_ItemCommand(ByVal source As Object, ByVal e As RepeaterCommandEventArgs) Handles cpRepeater.ItemCommand

        Dim lnkAtualizar As LinkButton = DirectCast(e.Item.FindControl("lnkAtualizar"), LinkButton)
        Dim lnkCancelar As LinkButton = DirectCast(e.Item.FindControl("lnkCancelar"), LinkButton)
        Dim lnkEditar As LinkButton = DirectCast(e.Item.FindControl("lnkEditar"), LinkButton)
        Dim lnkDeletar As LinkButton = DirectCast(e.Item.FindControl("lnkDeletar"), LinkButton)
        Dim lblNome As Label = DirectCast(e.Item.FindControl("lblNome"), Label)
        Dim lblrptID As Label = DirectCast(e.Item.FindControl("lblid"), Label)
        Dim txtNome As TextBox = DirectCast(e.Item.FindControl("txtNome"), TextBox)
        Dim ddlCurso As DropDownList = DirectCast(e.Item.FindControl("ddlCurso"), DropDownList)
        Dim chkDeletar As CheckBox = DirectCast(e.Item.FindControl("chkDeletar"), CheckBox)

        If e.CommandName = "edit" Then
            lnkCancelar.Visible = True
            lnkAtualizar.Visible = True
            lnkEditar.Visible = False
            txtNome.Visible = True

            lblNome.Visible = False
        End If

        If e.CommandName = "cancel" Then
            VinculaRepeater()
        End If

        If e.CommandName = "update" Then
            Dim SqlCnn As New SqlConnection(ConfigurationManager.AppSettings("ConnectionString"))
            Dim SqlCmd As New SqlCommand("update Lista set nome=@Nome, curso=@Curso where id=@ID", SqlCnn)
            SqlCmd.Parameters.Add("@nome", SqlDbType.VarChar).Value = txtNome.Text
            SqlCmd.Parameters.Add("@curso", SqlDbType.VarChar).Value = ddlCurso.SelectedItem.Text
            SqlCmd.Parameters.Add("@id", SqlDbType.VarChar).Value = e.CommandArgument
            Try
                SqlCnn.Open()

                SqlCmd.ExecuteNonQuery()
            Catch ex As Exception
                ex.Message.ToString()
            Finally
                If SqlCnn.State = ConnectionState.Open Then
                    SqlCnn.Close()
                End If
            End Try
            VinculaRepeater()
        End If
        If e.CommandName = "delete" Then
            Dim SqlCnn As New SqlConnection(ConfigurationManager.AppSettings("ConnectionString"))
            Dim SqlCmd As New SqlCommand("delete Lista where id=@ID", SqlCnn)
            SqlCmd.Parameters.Add("@ID", SqlDbType.VarChar).Value = e.CommandArgument
            Try
                SqlCnn.Open()

                SqlCmd.ExecuteNonQuery()
            Catch ex As Exception
                ex.Message.ToString()
            Finally
                If SqlCnn.State = ConnectionState.Open Then
                    SqlCnn.Close()
                End If
            End Try
            VinculaRepeater()
        End If

No evento ItemDataBound do controle Repeater é disparado a cada vez que um registro é incluído no controle, dessa forma, com esse evento podemos acessar os controles que são criados, bem como os dados que estão sendo vinculados as linhas; isso permite que você faça uma variedade de ações com esse evento como alterar dados , popular controles, etc.

No código do nosso exemplo estamos acessando a tabela Lista , criando um dataset e preenchendo o controle DropDownList (ddlCurso):

Protected Sub cpRepeater_ItemDataBound(ByVal sender As Object, ByVal e As RepeaterItemEventArgs) Handles cpRepeater.ItemDataBound

        Dim ddlCurso As DropDownList = DirectCast(e.Item.FindControl("ddlCurso"), DropDownList)

        If e.Item.ItemType = ListItemType.Item OrElse e.Item.ItemType = ListItemType.AlternatingItem Then
            Dim SqlCnn As New SqlConnection(ConfigurationManager.AppSettings("ConnectionString"))
            Dim SqlCmd As New SqlCommand("select * from Lista", SqlCnn)
            Dim Sqlda As New SqlDataAdapter(SqlCmd)
            Dim ds As New DataSet()
            Dim dt As New DataTable()
            Sqlda.Fill(dt)
            ddlCurso.DataTextField = "Curso"
            ddlCurso.DataSource = dt
            ddlCurso.DataBind()
            ddlCurso.SelectedValue = DataBinder.Eval(e.Item.DataItem, "curso").ToString()
        End If
    End Sub

No evento Click do linkButton - Deletar Selecionado - verificamos se o checkbox esta marcado para o registro e excluímos o mesmo da tabela em caso positivo;

Protected Sub LinkButton1_Click(ByVal sender As Object, ByVal e As System.EventArgs) Handles lnkDelSelecionado.Click
        For Each Item As RepeaterItem In cpRepeater.Items
            Dim chkDeletar As CheckBox = DirectCast(Item.FindControl("chkDeletar"), CheckBox)
            Dim lblrptID As Label = DirectCast(Item.FindControl("lblID"), Label)

            If chkDeletar.Checked Then
                Dim SqlCnn As New SqlConnection(ConfigurationManager.AppSettings("ConnectionString"))
                Dim SqlCmd As New SqlCommand("delete Lista where id=@ID", SqlCnn)
                SqlCmd.Parameters.Add("@ID", SqlDbType.VarChar).Value = lblrptID.Text
                SqlCmd.Connection = SqlCnn
                SqlCnn.Open()
                SqlCmd.ExecuteNonQuery()

                SqlCnn.Close()
            End If
        Next
        VinculaRepeater()

    End Sub

Abaixo vamos a página em execução para edição de dados:

Abaixo vemos o JavaScript em execução quando o escolhe excluir um registro:

Simples, simples assim...

No exemplo acima eu estou usando o código diretamente no code-behind por questão de simplicidade mas o ideal seria criar uma camada de acesso aos dados separando esse código da páginas ASPX.

Pegue o projeto completo aqui: RepeaterCRUD.zip

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

Referências:

José Carlos Macoratti