ASP .NET - ListView - Operações CRUD, páginação e classificação


Neste artigo vamos abordar novamente a utilização do controle ListView realizando operações CRUD, paginação e classificação em uma aplicação ASP .NET usando Web Forms.

Revisão de Conceitos

O controle ListView permite efetuar a vinculação de dados exibindo-os em uma página Web de forma individual ou agrupada com grande flexibilidade de formatação pela definição pelo desenvolvedor de templates e com recursos de tratamento de dados como paginação, edição, exclusão e inclusão.

O ListView apresenta uma maior flexibilidade na formatação de saída dos dados oferecendo ao desenvolvedor 11 templates para renderizar a saída HTML:

Dos templates acima os dois principais e de uso obrigatório são :

 LayoutTemplate
 - Define o conteúdo personalizado para o container principal do controle ListView. É usado para definir uma interface personalizada;
 - Para especificar o leiaute inclua um elemento LayoutTemplate em um controle ListView e a seguir inclua o conteúdo do template ao elemento.
 ItemTemplate
 - Define o conteúdo personalizado para o itens de dados em um controle ListView;
 - Geralmente contém os controles para exibir os valores dos campos de dados;

Como a definição dos controles LayoutTemplate e ItemTemplate é feita separadamente precisamos indicar ao LayoutTemplate os itens definidos pelo template ItemTemplate que deverão ser renderizados. Isto é feito pela inclusão de um controle de servidor com o um ID definido  pela propriedade ItemPlaceHolderID do controle ListView.

Dessa forma o LayoutTemplate precisa incluir um controle placeholder do lado do servidor com um atributo ID definido para o valor da propriedade ItemPlaceholderID ou GroupPlaceholderID.

Para acompanhar o exemplo deste artigo você vai precisar ter instalado os seguintes recursos:

- Visual Web Developer 2010 Express Edition (VWD 2010)
-
SQL Server 2005 Express
-
Banco de dados Northwind.mdf

Criando a aplicação ASP .NET

Nosso objetivo será criar uma aplicação ASP .NET Web Forms usando o controle ListView para realizar a manutenção da tabela Categories do banco de dados Northwind.mdf do SQL Server 2005.

Para isso vamos usar o controle ListView para realizar as operações de inclusão, alteração e exclusão de dados bem como usar os recursos de paginação e classificação do ListView efetuando a validação e também código JavaScript.

Abra o Visual Web Developer 2010 Express Edition e no menu File clique em New Web Site selecionando o template ASP .NET Web Site , a linguagem Visual C# e informando o nome ListView_CRUD;

Clique em OK para criar o novo web site;

O template ASP .NET Web Site já cria um novo web site com uma estrutura pronto incluindo uma Master Page (Site.master) , arquivos de scripts, estilo, autenticação, etc.

Vamos fazer alguns ajustes na Master Page, na página Default.aspx e vamos excluir a pasta Account do projeto.

Selecione a página Default.aspx e remova todo o código existente na tag <asp:content ID="BodyContent"...</asp:Content> conforme mostra a figura abaixo:

A seguir, a partir da ToolBox inclua na página Default.aspx os controles ListView e SqlDataSource conforme mostra a figura abaixo:

A partir disso iremos configurar os controles SqlDataSource e ListView para implementar todas as funcionalidades elencadas para a aplicação.

Definindo a fonte de dados

O controle SqlDataSource irá definir a nossa fonte de dados que será a tabela Categories do banco de dados Northwind.mdf.

No modo Design selecione o controle SqlDataSource e clique no link Configure DataSource;

Na janela do assistente selecione a conexão com o banco de dados Northwind.mdf e clique em Next>;

A seguir selecione a tabela Categories e selecione todos os campos conforme abaixo:

Clique em Next> e a seguir em Finish;

Dessa forma temos configurado a nossa fonte de dados;

Para encerrar esta etapa selecione o controle ListView na página Default.aspx e em Choose Data Source escolha o nome do controle que acabamos de configurar: SqlDataSource1

Configurando o controle ListView

Vamos agora iniciar a configuração do controle ListView definindo os templates que iremos precisar conforme mostra a figura abaixo:

Vamos começar definindo os templates LayoutTemplate e ItemTemplate;

A configuração dos templates é mostrada a seguir:

<LayoutTemplate>
     <table border="0" cellpadding="1">
      <tr style="background-color:#E5E5FE">
        <th align="left"><asp:LinkButton ID="lnkId" runat="server" CommandName="Sort" CommandArgument="CategoryID">Código</asp:LinkButton></th>
        <th align="left"><asp:LinkButton ID="lnkName" runat="server" CommandName="Sort" CommandArgument="CategoryName">Nome</asp:LinkButton></th>
        <th align="left"><asp:LinkButton ID="lnkType" runat="server" CommandName="Sort" CommandArgument="Description">Descrição</asp:LinkButton></th>
      <th></th>
     </tr>
     <tr id="itemPlaceholder" runat="server"></tr>
     </table>
</LayoutTemplate>

<ItemTemplate>
  <tr>
   <td><asp:Label runat="server" ID="lblCod"><%#Eval("CategoryID") %></asp:Label></td>
   <td><asp:Label runat="server" ID="lblName"><%#Eval("CategoryName")%></asp:Label></td>
   <td><asp:Label runat="server" ID="lblDesc"><%#Eval("Description") %></asp:Label></td>
   <td><asp:LinkButton ID="lnkEdit" runat="server" CommandName="Edit">Editar</asp:LinkButton></td>
   <td></td>
  </tr>
</ItemTemplate>

<AlternatingItemTemplate>
  <tr style="background-color:#EFEFEF">
   <td><asp:Label runat="server" ID="lblId"><%#Eval("CategoryID")%></asp:Label></td>
   <td><asp:Label runat="server" ID="lblNome"><%#Eval("CategoryName")%></asp:Label></td>
   <td><asp:Label runat="server" ID="lblDesc"><%#Eval("Description") %></asp:Label></td>
   <td><asp:LinkButton ID="lnkEdit" runat="server" CommandName="Edit">Editar</asp:LinkButton></td>
   <td></td>
  </tr>
</AlternatingItemTemplate>

No código acima definimos no template LayoutTemplate o nível superior de saída para renderização HTML; Note que estamos usando o controle LinkButton para criar links no cabeçalho do ListView e aplicando o comando de classificação Sort na propriedade CommandName e informando o argumento da classificação na propriedade CommandArgument, no caso os campos CategoryID, CategoryName e Description da nossa tabela Categories;

Para exibir os dados usamos os templates ItemTemplate e AlternatingItemTemplate para mostrar linhas com uma formatação diferente definida em um arquivo de estilo CSS. O ItemTemplate esta exibindo os dados obtidos da tabela Categoria que são exibidos em controles Label usando o método Eval(); O AlternativeItemTemplate exibe os mesmos dados alterando o estilo CSS para colunas alternadas.

Definindo a paginação

Para definir a paginação vamos incluir um controle DataPager no template LayoutTemplate conforme mostra o código abaixo:

<LayoutTemplate>
     <table border="0" cellpadding="1">
      <tr style="background-color:#E5E5FE">
        <th align="left"><asp:LinkButton ID="lnkId" runat="server" CommandName="Sort" CommandArgument="CategoryID">Código</asp:LinkButton></th>
        <th align="left"><asp:LinkButton ID="lnkName" runat="server" CommandName="Sort" CommandArgument="CategoryName">Nome</asp:LinkButton></th>
        <th align="left"><asp:LinkButton ID="lnkType" runat="server" CommandName="Sort" CommandArgument="Description">Descrição</asp:LinkButton></th>
      <th></th>
     </tr>
     <tr id="itemPlaceholder" runat="server"></tr>
     </table>

    <asp:DataPager ID="ItemDataPager" runat="server" PageSize="5">
        <Fields>
             <asp:NumericPagerField ButtonCount="3" />
        </Fields>
    </asp:DataPager> 
</LayoutTemplate>

O código do DataPager define o tamanho da página (PageSize) como 5 linhas e o tipo de paginador que será exibido bem como a quantidade de itens exibidos no paginador, no caso 3.

Definindo as operações CRUD

Para definir as operações CRUD como alterar e editar usamos os templates InsertItemTemplate e EditItemTemplate:

O template InsertItemTemplate define um conteúdo personalizado para os itens no modo de inserção.

No código estamos exibindo o controle TextBox e renderizando os valores CategoryName e Description da tabela Categories usando a propriedade Eval();

Definimos também um controle Button com a propriedade CommandName que define o nome do comando associado ao controle que é passado para o evento Command que será tratado no code-behind.

A propriedade CausesValidation definida como true indica que a página será validada quando o botão for clicado; para isso definimos um grupo de validação na propriedade validationgroup e usamos os controles RequiredFieldValidator para validar os campos nome da categoria (txtCatNome) e descrição (txtCatDesc).

Observe que definimos o grupo de validação fora do controle ListView enquanto que os controles para validação foram definidos no template onde desejamos realizar a validação.

<InsertItemTemplate>

    <tr id="Tr1" runat="server">
        <td></td>
        <td><asp:TextBox ID="txtCatNome" runat="server" Text='<%#Eval("CategoryName") %>' Width="100px">Nome</asp:TextBox></td>
        <td><asp:TextBox ID="txtCatDesc" runat="server" Text='<%#Eval("Description") %>' Width="340px">Descrição</asp:TextBox></td>
        <td><asp:Button ID="InsertButton" runat="server" CommandName="Insert" Text="Inserir" causesvalidation="true" validationgroup="Insertvalidation"  /></td>
    </tr>

    <asp:RequiredFieldValidator ID="RV4" ControlToValidate="txtCatNome"
            runat="server" ErrorMessage="Informe o nome da categoria."
            Display="Dynamic"
            ValidationGroup="Insertvalidation">*</asp:RequiredFieldValidator>
    <asp:RequiredFieldValidator ID="RequiredFieldValidator1" ControlToValidate="txtCatDesc"
            runat="server" ErrorMessage="Informe a descrição da categoria."
            Display="Dynamic"
            ValidationGroup="Insertvalidation">*</asp:RequiredFieldValidator>

</InsertItemTemplate>   

 <EditItemTemplate>
   <td><asp:TextBox ID="txtId" runat="server" Text='<%#Eval("CategoryID") %>' Enabled="false" Width="20px"></asp:TextBox></td>
   <td><asp:TextBox ID="txtCatNome" runat="server" Text='<%#Eval("CategoryName") %>' Width="100px"></asp:TextBox></td>
   <td><asp:TextBox ID="txtCatDesc" runat="server" Text='<%#Eval("Description") %>' Width="340px"></asp:TextBox></td>
   <td>   
      <asp:LinkButton ID="lnkUpdate" runat="server" CommandName="Update">Atualizar</asp:LinkButton>
      <asp:LinkButton ID="lnkDelete" runat="server" CommandName="Delete" OnClientClick="javascript:return confirm('Confirma exclusão deste Item ?');">Deletar</asp:LinkButton>
      <asp:LinkButton ID="lnkCancel" runat="server" CommandName="Cancel">Cancelar</asp:LinkButton>
   </td>
  </tr>
 </EditItemTemplate> 
</asp:ListView>

<asp:ValidationSummary ID="ValidationSummary1" runat="server" ShowMessageBox="true" ShowSummary="false" ValidationGroup="Insertvalidation" />

Usamos a propriedade EditItemTemplate para definir o conteúdo personalizado para exibir um item que está em modo de edição em um objeto TemplateField.

No template definimos que os valores dos campos da tabela Categories obtidas pelo binding usando o método Eval serão exibidos em controles TextBox, onde a coluna CategoryID esta desabilitada (Enabled=False) visto que não vamos editar o código da categoria por ser um valor atribuído pelo banco de dados.

Definimos também os links para Atualizar(Update), Deletar(Delete) e Cancelar(Cancel) a edição onde no link Delete usamos o código JavaScript para confirmar a exclusão de um item.

Ao término dessas configurações e definições deveremos obter o seguinte leiaute para a página Default.aspx:

Definindo o código no arquivo Default.aspx.cs

Para concluir temos que definir o código no arquivo code-behind Default.aspx.cs onde identificamos qual o comando foi acionado e definimos a ação correspondente usando comandos SQL para :

sing System.Web.UI.WebControls;

public partial class _Default : System.Web.UI.Page
{
    protected void Page_Load(object sender, EventArgs e)
    { }
    protected void ListView1_ItemCommand(object sender, ListViewCommandEventArgs e)
    {
        if (e.CommandName == "Insert")
        {
            TextBox txtCatNome = (TextBox)e.Item.FindControl("txtCatNome");
            TextBox txtCatDesc = (TextBox)e.Item.FindControl("txtCatDesc");

            string insertCommand = "Insert into [Categories] ([CategoryName],[Description],[Picture]) Values('" + txtCatNome.Text + "', '" + txtCatDesc.Text + "', '" + "" + "');";
            SqlDataSource1.InsertCommand = insertCommand;
        }
        else if (e.CommandName == "Update")
        {
            TextBox txtId = (TextBox)e.Item.FindControl("txtId");
            TextBox txtCatNome = (TextBox)e.Item.FindControl("txtCatNome");
            TextBox txtCatDesc = (TextBox)e.Item.FindControl("txtCatDesc");
            string updateCommand = "Update Categories set CategoryName='" + txtCatNome.Text + "', Description='" + txtCatDesc.Text + "' where CategoryID=" + Convert.ToInt32(txtId.Text) + ";";
            SqlDataSource1.UpdateCommand = updateCommand;
        }
        else if (e.CommandName == "Delete")
        {
            TextBox txtId = (TextBox)e.Item.FindControl("txtId");
            string deleteCommand = "delete from [Categories] where CategoryID=" + Convert.ToInt32(txtId.Text);
            SqlDataSource1.DeleteCommand = deleteCommand;
        }
    }
}

Executando a aplicação teremos a exibição da página Default.aspx onde podemos realizar a manutenção dos dados da tabela Categories usando o controle ListView com recursos de paginação e classificação e inclusão de dados:

Pegue o projeto completo com aqui : ListView_CRUD.zip

1Pedro 1:13 Portanto, cingindo os lombos do vosso entendimento, sede sóbrios, e esperai inteiramente na graça que se vos oferece na revelação de Jesus Cristo.
1Pedro 1:14
Como filhos obedientes, não vos conformeis às concupiscências que antes tínheis na vossa ignorância;
1Pedro 1:15
mas, como é santo aquele que vos chamou, sede vós também santos em todo o vosso procedimento;

1Pedro 1:16
porquanto está escrito: Sereis santos, porque eu sou santo.

Referências:


José Carlos Macoratti