ASP .NET -  Realizando as operações CRUD em arquivos XML com ListView

 Neste artigo vamos realizar as operações de leitura, inclusão, alteração e exclusão de dados em um arquivo XML usando um controle ListView da ASP .NET Web Forms.

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.

Embora os controles já existentes (DataGridView, DataRepeater, etc.) apresentassem diversos recursos que poderiam ser usados em determinadas situações, faltava uma maior flexibilidade na apresentação e no tratamento das informações.

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 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.

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.

Objetivo

Carregar um arquivo XML em um controle ListView e realizar as operações CRUD em uma aplicação ASP .NET Web Forms usando a linguagem C#.

Recursos usados:

Criando o web site e definindo o arquivo XML

Abra o Visual Studio 2012 Express for Web e clique em New Web Site;

Selecione a linguagem Visual C#  e o template ASP .NET Empty Web Site e informe o nome ListView_XML_Crud;

A seguir no menu WEBSITE clique em Add New Item e selecione o template WebForm aceitando no nome padrão Default.aspx;

Vamos agora criar um arquivo XML que será nossa fonte de dados.

No menu WEBSITE clique em Add New Item e selecione o template XML File informando o nome Filmes.xml;

Defina o seguinte código no arquivo Filmes.xml:

Temos aqui um arquivo XML que mostra uma estrutura onde temos a raiz <Filmes> e o nó filho <Filme> que apresenta informações sobre filmes usando as tags : Nome, Ano ,Genero e Atores.

A seguir selecione o arquivo Default.aspx abrindo-o no editor e ative o modo Source.

A partir da ToolBox inclua um controle ListView entre as tags <div> do formulário form1 da página.

A seguir defina o seguinte código na página Default.aspx:

<%@ Page Language="C#" AutoEventWireup="true" CodeFile="Default.aspx.cs" Inherits="_Default" %>
<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml">
<head runat="server">
    <title>ListView - CRUD em arquivo XML </title>
</head>
<body>
    <form id="form1" runat="server">
    <div>
       <asp:ListView ID="FilmesListView" runat="server"
            InsertItemPosition="LastItem" OnItemInserting="FilmesListView_ItemInserting"
            OnItemDeleting="FilmesListView_ItemDeleting" OnItemEditing="FilmesListView_ItemEditing"
            OnItemCanceling="FilmesListView_ItemCanceling" >
              <LayoutTemplate>
               <table id="tblFilmes" runat="server" width="100%" >
                 <tr id="Tr1" runat="server">
                 <td id="Td1" runat="server">
                 <table id="itemPlaceholderContainer" runat="server" border="0" style="" width="100%">
                  <tr id="Tr2" runat="server" style="">
                  <th id="Th1" runat="server"></th>
                  <th id="Th2" runat="server">Nome</th>
                  <th id="Th3" runat="server">Ano</th>
                  <th id="Th4" runat="server">Genero</th>
                  <th id="Th5" runat="server">Atores</th>
                  </tr>
                  <tr id="itemPlaceholder" runat="server"></tr></table></td></tr>
                  <tr id="Tr3" runat="server">
                  <td id="Td2" runat="server" style=""></td>
                  </tr>
                </table>
               </LayoutTemplate>
            <ItemTemplate>
              <tr style="">
              <td>
              <asp:Button ID="btnDeletar" runat="server" CommandName="Delete" Text="Deletar" />
              <asp:Button ID="btnEditar" runat="server" CommandName="Edit" Text="Editar" />
              </td>
               <td><asp:Label ID="lblNome" runat="server" Text='<%# Bind("Nome") %>' /></td>
               <td><asp:Label ID="lblAno" runat="server" Text='<%# Bind("Ano") %>' /></td>
               <td><asp:Label ID="lblGenero" runat="server" Text='<%# Bind("Genero") %>' /></td>
               <td><asp:Label ID="lblAtores" runat="server" Text='<%# Bind("Atores") %>' /></td>
               </tr>
            </ItemTemplate>
            <InsertItemTemplate>
              <tr style="">
              <td>
              <asp:Button ID="btnInserir" runat="server" CommandName="Insert" Text="Inserir" />
              <asp:Button ID="btnCancelar" runat="server" CommandName="Cancel" Text="Limpar" />
              </td>        
              <td><asp:TextBox ID="txtNome" runat="server" Text='<%# Bind("Nome") %>' /></td>
              <td><asp:TextBox ID="txtAno" runat="server" Text='<%# Bind("Ano") %>' /></td>
              <td><asp:TextBox ID="txtGenero" runat="server" Text='<%# Bind("Genero") %>' /></td>
              <td><asp:TextBox ID="txtAtores" runat="server" Text='<%# Bind("Atores") %>' /></td>
              <td><asp:Button ID="btnAtualizar" runat="server" Text="Atualizar" OnClick="btnAtualizar_Click" /></td>
              </tr>
            </InsertItemTemplate>
       </asp:ListView>       
    </div>
    </form>
</body>
</html>

No código da página Default.aspx definimos um controle ListView e os templates :

Definimos também os seguintes eventos no controle ListView:

Definimos também 5 controles Button sendo que 4 deles associados a CommandName e 1 ao evento OnClick :

Ativando o modo Design podemos visualizar o leiaute da página conforme abaixo:

Definindo o código da página

Agora vamos definir o código da página no arquivo code-behind Default.aspx.cs.

Primeiro vamos declarar os namespaces usados:

using System;

using System.Web.UI;

using System.Web.UI.WebControls;

using System.Data;

using System.Xml;

A seguir, logo após à declaração do formulário vamos definir a variável arquivoXML que irá armazenar o nome e caminho do arquivo XML.

string arquivoXML = "";

No evento Load da página definimos o seguinte código:

 protected void Page_Load(object sender, EventArgs e)
 {
        if (!Page.IsPostBack) 
        {
            arquivoXML = Server.MapPath("~/Filmes.xml");
            carregaDados(); 
        }
 }

O código verifica se não é um postback e neste caso obtém o nome e caminho do arquivo XML do projeto e chama a rotina carregaDados();

Nota:  O PostBack é uma ação que ocorre em uma página que envia dados para o servidor; esse faz o processamento e validações do conteúdo e retorna o resultado ao navegador do cliente.

O código dessa rotina é vista a seguir:

protected void carregaDados()
{
        DataSet ds = new DataSet();

        ds.ReadXml(arquivoXML);
        FilmesListView.DataSource = ds;
        FilmesListView.DataBind();
}

Agora vamos selecionar o controle ListView na página Default.aspx e na página de propriedades do controle vamos ativar a visualização dos eventos onde iremos visualizar o seguinte :

Vamos clicar em cada um dos eventos para gerar o código na página Default.aspx.cs para posterior implementação e vamos definir também o evento btnAtualizar_Click().

No código da página iremos obter o seguinte:

    protected void FilmesListView_ItemCanceling(object sender, ListViewCancelEventArgs e)
    {    }

    protected void FilmesListView_ItemDeleting(object sender, ListViewDeleteEventArgs e)
    {    }

    protected void FilmesListView_ItemEditing(object sender, ListViewEditEventArgs e)
    {    }

    protected void FilmesListView_ItemInserting(object sender, ListViewInsertEventArgs e)
    {  }    

    protected void btnAtualizar_Click(object sender, EventArgs e)
    {    }

Neste momento podemos executar o projeto do Web Site para vermos os dados carregados na página:

Note que a última linha é usada para exibir a linha selecionada pelo usuário no controle ListView permitindo sua alteração.

Como não temos nenhuma funcionalidade ainda implementada, vamos agora definir o código de cada um dos eventos acima.

Vamos lá...

1- ItemInserting - Inclui um novo nó filho no arquivo XML com informações de Nome, Ano, Gênero e Atores

 protected void FilmesListView_ItemInserting(object sender, ListViewInsertEventArgs e)
    {
        arquivoXML = Server.MapPath("~/Filmes.xml");
        TextBox txtNomeTextBox = (TextBox)FilmesListView.InsertItem.FindControl("txtNome");
        TextBox txtAnoTextBox = (TextBox)FilmesListView.InsertItem.FindControl("txtAno");
        TextBox txtGeneroTextBox = (TextBox)FilmesListView.InsertItem.FindControl("txtGenero");
        TextBox txtAtoresTextBox = (TextBox)FilmesListView.InsertItem.FindControl("txtAtores");
        XmlDocument xmlDoc = new XmlDocument();
        xmlDoc.Load(arquivoXML);
        XmlElement xelement = xmlDoc.CreateElement("Filme");
        XmlElement xName = xmlDoc.CreateElement("Nome");
        xName.InnerText = txtNomeTextBox.Text;
        xelement.AppendChild(xName);
        XmlElement xYear = xmlDoc.CreateElement("Ano");
        xYear.InnerText = txtAnoTextBox.Text;
        xelement.AppendChild(xYear);
        XmlElement xGenre = xmlDoc.CreateElement("Genero");
        xGenre.InnerText = txtGeneroTextBox.Text;
        xelement.AppendChild(xGenre);
        XmlElement xCast = xmlDoc.CreateElement("Autores");
        xCast.InnerText = txtAtoresTextBox.Text;
        xelement.AppendChild(xCast);
        xmlDoc.DocumentElement.AppendChild(xelement);
        xmlDoc.Save(arquivoXML);
        carregaDados();
 }

2- ItemEditing - Permite que uma linha do controle ListView seja selecionada e exibida nos controles TextBox da página para alteração:

protected void FilmesListView_ItemEditing(object sender, ListViewEditEventArgs e)
 {
        arquivoXML = Server.MapPath("~/Filmes.xml");
        FilmesListView.EditIndex = e.NewEditIndex;
        i = Convert.ToInt16(FilmesListView.EditIndex);
        Label lblNome = (Label)FilmesListView.EditItem.FindControl("lblNome");
        Label lblAno = (Label)FilmesListView.EditItem.FindControl("lblAno");
        Label lblGenero = (Label)FilmesListView.EditItem.FindControl("lblGenero");
        Label lblAtores = (Label)FilmesListView.EditItem.FindControl("lblAtores");
        TextBox txtNomeTextBox = (TextBox)FilmesListView.InsertItem.FindControl("txtNome");
        TextBox txtAnoTextBox = (TextBox)FilmesListView.InsertItem.FindControl("txtAno");
        TextBox txtGeneroTextBox = (TextBox)FilmesListView.InsertItem.FindControl("txtGenero");
        TextBox txtAtoresTextBox = (TextBox)FilmesListView.InsertItem.FindControl("txtAtores");
        txtNomeTextBox.Text = lblNome.Text;
        txtAnoTextBox.Text = lblAno.Text;
        txtGeneroTextBox.Text = lblGenero.Text;
        txtAtoresTextBox.Text = lblAtores.Text;
 }

3-  ItemDeleting - Permite excluir um nó filho do arquivo XML quando o usuário clica no botão Deletar no controle ListView

protected void FilmesListView_ItemDeleting(object sender, ListViewDeleteEventArgs e)
 {
        arquivoXML = Server.MapPath("~/Filmes.xml");
        Label lblNome = (FilmesListView.Items[e.ItemIndex].FindControl("lblNome")) as Label;
        Label lblAno = (FilmesListView.Items[e.ItemIndex].FindControl("lblAno")) as Label;
        Label lblGenero = (FilmesListView.Items[e.ItemIndex].FindControl("lblGenero")) as Label;
        Label lblAtores = (FilmesListView.Items[e.ItemIndex].FindControl("lblAtores")) as Label;
        XmlDocument xmlDoc = new XmlDocument();
        xmlDoc.Load(arquivoXML);
        XmlNodeList newXMLNodes = xmlDoc.SelectNodes("/Filmes/Filme");
        string nomedoFilme = lblNome.Text;
        foreach (XmlNode newXMLNode in newXMLNodes)
        {
            if (newXMLNode.InnerText.Contains(nomedoFilme))
            {
                newXMLNode.ParentNode.RemoveChild(newXMLNode);
            }
        }
        xmlDoc.Save(arquivoXML);
        xmlDoc = null;
        carregaDados();
  }

4- ItemCanceling - Permite limpar as caixas de texto no controle ListView quando o usuário clica no botão Limpar

protected void FilmesListView_ItemCanceling(object sender, ListViewCancelEventArgs e)
 {
        TextBox txtNomeTextBox = (TextBox)FilmesListView.InsertItem.FindControl("txtNome");
        TextBox txtAnoTextBox = (TextBox)FilmesListView.InsertItem.FindControl("txtAno");
        TextBox txtGeneroTextBox = (TextBox)FilmesListView.InsertItem.FindControl("txtGenero");   
        TextBox txtAtoresTextBox = (TextBox)FilmesListView.InsertItem.FindControl("txtAtores");
        txtNomeTextBox.Text = string.Empty;
        txtAnoTextBox.Text = string.Empty;
        txtGeneroTextBox.Text = string.Empty;
        txtAtoresTextBox.Text = string.Empty;
   }

5-  btnAtualizar_CliCk - Este código é executado quando o usuário clica no botão Atualizar e inclui um novo Nó filho no arquivo XML persistindo as alterações feitas

 protected void btnAtualizar_Click(object sender, EventArgs e)
    {
        arquivoXML = Server.MapPath("~/Filmes.xml");
        TextBox txtNomeTextBox = (TextBox)FilmesListView.InsertItem.FindControl("txtNome");
        TextBox txtAnoTextBox = (TextBox)FilmesListView.InsertItem.FindControl("txtAno");
        TextBox txtGeneroTextBox = (TextBox)FilmesListView.InsertItem.FindControl("txtGenero");
        TextBox txtAtoresTextBox = (TextBox)FilmesListView.InsertItem.FindControl("txtAtores");
        XmlDocument xmldoc = new XmlDocument();
        xmldoc.Load(arquivoXML);
        XmlNode xmlnode = xmldoc.DocumentElement.ChildNodes.Item(i);
        xmlnode["Nome"].InnerText = txtNomeTextBox.Text;
        xmlnode["Ano"].InnerText = txtAnoTextBox.Text;
        xmlnode["Genero"].InnerText = txtGeneroTextBox.Text;
        xmlnode["Atores"].InnerText = txtAtoresTextBox.Text;
        xmldoc.Save(arquivoXML);
        carregaDados();
    }

Observe que em todos os códigos estamos usando o  método FindControl que procura no controle atual por um controle filho com o id informado.

Usamos o FindControl para acessar um controle a partir de uma função no código da página, para acessar um controle que está dentro de outro recipiente, ou em outras circunstâncias em que o controle de destino não está acessível diretamente para o chamador.

Esse método irá encontrar um controle somente se o controle estiver contido diretamente pelo contêiner especificado; ou seja, o método não pesquisa em toda uma hierarquia de controles nos controles.

Executando o projeto e realizando algumas operações teremos o seguinte resultado:

Pegue o projeto completo aqui :    ListView_XML_Crud.zip 

Flp 3:1 Quanto ao mais, irmãos meus, regozijai-vos no Senhor. Não me é penoso a mim escrever-vos as mesmas coisas, e a vós vos dá segurança.

Flp 3:2 Acautelai-vos dos cães; acautelai-vos dos maus obreiros; acautelai-vos da falsa circuncisão.

Veja os Destaques e novidades do SUPER DVD Visual Basic (sempre atualizado) : clique e confira !

Quer migrar para o VB .NET ?

Quer aprender C# ??

 

             Gostou ?   Compartilhe no Facebook   Compartilhe no Twitter
 

Referências:


José Carlos Macoratti