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:
- AlternatingItemTemplate
- EditItemTemplate
- EmptyDataTemplate
- EmptyItemTemplate
- GroupSeparatorTemplate
- GroupTemplate
- InsertItemTemplate
- ItemSeparatorTemplate
- ItemTemplate
- LayoutTemplate
- SelectedItemTemplate
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.
O 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:
- Visual Studio Express 2012 for web
- Linguagem C#
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:
- LayoutTemplate
- ItemTemplate
- InsertItemTemplate
Definimos também os seguintes eventos no controle ListView:
- OnItemInserting
- OnItemDeleting
- OnItemEditing
- OnItemCanceling
Definimos também 5 controles Button sendo que 4 deles associados a CommandName e 1 ao evento OnClick:
- btnDeletar – CommandName=”Delete”
- btnEditar – CommandName=”Edit”
- btnInserir – CommandName=”Insert”
- btnCancelar – CommandName=”Cancel”
- btnAtualizar – evento OnClick=”btnAtualizar_Click”
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 eventobtnAtualizar_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 ele 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