Nota
O acesso a esta página requer autorização. Pode tentar iniciar sessão ou alterar os diretórios.
O acesso a esta página requer autorização. Pode tentar alterar os diretórios.
por Scott Mitchell
Neste tutorial, veremos como mapear os métodos Insert(), Update() e Delete() de um ObjectDataSource para os métodos de classes BLL, bem como configurar os controles GridView, DetailsView e FormView para fornecer recursos de modificação de dados.
Introdução
Nos últimos tutoriais, examinamos como exibir dados em uma página ASP.NET usando os controles GridView, DetailsView e FormView. Esses controles simplesmente funcionam com os dados fornecidos a eles. Geralmente, esses controles acessam dados por meio do uso de um controle de fonte de dados, como o ObjectDataSource. Vimos como o ObjectDataSource atua como um proxy entre a página ASP.NET e os dados subjacentes. Quando um GridView precisa exibir dados, invoca o método Select() do seu ObjectDataSource, que por sua vez invoca um método da nossa Camada de Lógica de Negócios (BLL), que chama um método no Adaptador de Tabela (TableAdapter) da camada de acesso a dados apropriada (DAL), que, por sua vez, envia uma consulta SELECT para o banco de dados Northwind.
Lembre-se de que, quando criamos os TableAdapters na DAL em nosso primeiro tutorial, o Visual Studio adicionou automaticamente métodos para inserir, atualizar e excluir dados da tabela de banco de dados subjacente. Além disso, em Criar uma Camada de Lógica de Negócios , projetámos métodos na BLL que recorriam aos métodos de modificação de dados da DAL.
Além de seu Select() método, o ObjectDataSource também tem Insert(), Update()e Delete() métodos. Como o Select() método, esses três métodos podem ser mapeados para métodos em um objeto subjacente. Quando configurado para inserir, atualizar ou excluir dados, os controles GridView, DetailsView e FormView fornecem uma interface do usuário para modificar os dados subjacentes. Esta interface do utilizador chama os métodos Insert(), Update() e Delete() do ObjectDataSource, que então invocam os métodos associados do objeto subjacente (consulte a Figura 1).
Figura 1: Os métodos Insert(), Update(), e Delete() do ObjectDataSource servem como um proxy para a BLL (Clique para visualizar a imagem em tamanho real)
Neste tutorial, veremos como mapear os métodos Insert(), Update() e Delete() do ObjectDataSource para os métodos de classes na BLL, bem como como configurar os controlos GridView, DetailsView e FormView para fornecer recursos de modificação de dados.
Etapa 1: Criar as páginas da Web dos tutoriais sobre Inserir, Atualizar e Excluir
Antes de começarmos a explorar como inserir, atualizar e excluir dados, vamos primeiro reservar um momento para criar as páginas ASP.NET em nosso projeto de site que precisaremos para este tutorial e os próximos vários. Comece adicionando uma nova pasta chamada EditInsertDelete. Em seguida, adicione as seguintes páginas ASP.NET a essa pasta, certificando-se de associar cada página à Site.master página mestra:
Default.aspxBasics.aspxDataModificationEvents.aspxErrorHandling.aspxUIValidation.aspxCustomizedUI.aspxOptimisticConcurrency.aspxConfirmationOnDelete.aspxUserLevelAccess.aspx
Figura 2: Adicionar as Páginas do ASP.NET para os Tutoriais de Dados Modification-Related
Como nas outras pastas, Default.aspx na EditInsertDelete pasta irá listar os tutoriais em sua seção. Lembre-se de que o SectionLevelTutorialListing.ascx Controle de Usuário fornece essa funcionalidade. Portanto, adicione este User Control a Default.aspx arrastando-o do Gerenciador de Soluções para a Vista de Design da página.
Figura 3: Adicionar o controle de usuário a SectionLevelTutorialListing.ascx (Default.aspx imagem em tamanho real)
Por fim, adicione as páginas como entradas ao Web.sitemap arquivo. Especificamente, adicione a seguinte marcação após a formatação <siteMapNode>personalizada :
<siteMapNode title="Editing, Inserting, and Deleting"
url="~/EditInsertDelete/Default.aspx"
description="Samples of Reports that Provide Editing, Inserting,
and Deleting Capabilities">
<siteMapNode url="~/EditInsertDelete/Basics.aspx"
title="Basics"
description="Examines the basics of data modification with the
GridView, DetailsView, and FormView controls." />
<siteMapNode url="~/EditInsertDelete/DataModificationEvents.aspx"
title="Data Modification Events"
description="Explores the events raised by the ObjectDataSource
pertinent to data modification." />
<siteMapNode url="~/EditInsertDelete/ErrorHandling.aspx"
title="Error Handling"
description="Learn how to gracefully handle exceptions raised
during the data modification workflow." />
<siteMapNode url="~/EditInsertDelete/UIValidation.aspx"
title="Adding Data Entry Validation"
description="Help prevent data entry errors by providing validation." />
<siteMapNode url="~/EditInsertDelete/CustomizedUI.aspx"
title="Customize the User Interface"
description="Customize the editing and inserting user interfaces." />
<siteMapNode url="~/EditInsertDelete/OptimisticConcurrency.aspx"
title="Optimistic Concurrency"
description="Learn how to help prevent simultaneous users from
overwritting one another s changes." />
<siteMapNode url="~/EditInsertDelete/ConfirmationOnDelete.aspx"
title="Confirm On Delete"
description="Prompt a user for confirmation when deleting a record." />
<siteMapNode url="~/EditInsertDelete/UserLevelAccess.aspx"
title="Limit Capabilities Based on User"
description="Learn how to limit the data modification functionality
based on the user role or permissions." />
</siteMapNode>
Após a atualização Web.sitemap, reserve um momento para visualizar o site de tutoriais através de um navegador. O menu à esquerda agora inclui itens para os tutoriais de edição, inserção e exclusão.
Figura 4: O mapa do site agora inclui entradas para os tutoriais de edição, inserção e exclusão
Etapa 2: Adicionando e configurando o controle ObjectDataSource
Como GridView, DetailsView e FormView diferem em seus recursos e layout de modificação de dados, vamos examinar cada um individualmente. Em vez de ter cada controle usando seu próprio ObjectDataSource, no entanto, vamos apenas criar um único ObjectDataSource que todos os três exemplos de controle podem compartilhar.
Abra a Basics.aspx página, arraste um ObjectDataSource do Painel de Ferramentas para o Designer e clique no link Configurar Fonte de Dados do seu smart tag. Como a ProductsBLL é a única classe BLL que fornece métodos de edição, inserção e exclusão, configure o ObjectDataSource para usar essa classe.
Figura 5: Configurar o ObjectDataSource para usar a classe (ProductsBLL imagem em tamanho real)
Na próxima tela, podemos especificar quais métodos da classe ProductsBLL são mapeados para o Select(), Insert(), Update() e Delete() do ObjectDataSource, selecionando a guia apropriada e escolhendo o método na lista suspensa. A Figura 6, que já deve parecer familiar, mapeia o método Select() do ObjectDataSource ao método ProductsBLL da classe GetProducts(). Os métodos Insert(), Update() e Delete() podem ser configurados selecionando a guia apropriada na lista ao longo da parte superior.
Figura 6: Fazer com que o ObjectDataSource retorne todos os produtos (Clique para visualizar a imagem em tamanho real)
As Figuras 7, 8 e 9 mostram as guias UPDATE, INSERT e DELETE do ObjectDataSource. Configure estas guias para que os métodos Insert(), Update() e Delete() invoquem os métodos ProductsBLL, UpdateProduct e AddProduct da classe DeleteProduct, respetivamente.
Figura 7: Mapeie o método do Update() ObjectDataSource para o método da ProductBLL classe (UpdateProduct imagem em tamanho real)
Figura 8: Mapear o método Insert() do ObjectDataSource para o método Add da ProductBLL Classe Product (Clique para visualizar a imagem em tamanho real)
Figura 9: Mapear o método do ObjectDataSource Delete() para o método da classe ProductBLLDeleteProduct (Clique para visualizar a imagem em tamanho real)
Você deve ter notado que as listas suspensas nas guias UPDATE, INSERT e DELETE já tinham esses métodos selecionados. Isto é graças ao nosso uso do DataObjectMethodAttribute que decora os métodos de ProductsBLL. Por exemplo, o método DeleteProduct tem a seguinte assinatura:
[System.ComponentModel.DataObjectMethodAttribute
(System.ComponentModel.DataObjectMethodType.Delete, true)]
public bool DeleteProduct(int productID)
{
...
}
O DataObjectMethodAttribute atributo indica a finalidade de cada método, seja para selecionar, inserir, atualizar ou excluir e se é ou não o valor padrão. Se você omitiu esses atributos ao criar suas classes BLL, precisará selecionar manualmente os métodos nas guias UPDATE, INSERT e DELETE.
Depois de garantir que os métodos adequados ProductsBLL sejam mapeados para os métodos Insert(), Update() e Delete() do ObjectDataSource, clique em Concluir para terminar o assistente.
Examinando a marcação do ObjectDataSource
Depois de configurar o ObjectDataSource por meio de seu assistente, vá para a visualização Source para examinar a marcação declarativa gerada. A <asp:ObjectDataSource> tag especifica o objeto subjacente e os métodos a serem invocados. Além disso, existem DeleteParameters, UpdateParameters e InsertParameters que mapeiam para os parâmetros de entrada da classe ProductsBLL e os métodos AddProduct, UpdateProduct e DeleteProduct.
<asp:ObjectDataSource ID="ObjectDataSource1" runat="server"
DeleteMethod="DeleteProduct" InsertMethod="AddProduct"
OldValuesParameterFormatString="original_{0}" SelectMethod="GetProducts"
TypeName="ProductsBLL" UpdateMethod="UpdateProduct">
<DeleteParameters>
<asp:Parameter Name="productID" Type="Int32" />
</DeleteParameters>
<UpdateParameters>
<asp:Parameter Name="productName" Type="String" />
<asp:Parameter Name="supplierID" Type="Int32" />
<asp:Parameter Name="categoryID" Type="Int32" />
<asp:Parameter Name="quantityPerUnit" Type="String" />
<asp:Parameter Name="unitPrice" Type="Decimal" />
<asp:Parameter Name="unitsInStock" Type="Int16" />
<asp:Parameter Name="unitsOnOrder" Type="Int16" />
<asp:Parameter Name="reorderLevel" Type="Int16" />
<asp:Parameter Name="discontinued" Type="Boolean" />
<asp:Parameter Name="productID" Type="Int32" />
</UpdateParameters>
<InsertParameters>
<asp:Parameter Name="productName" Type="String" />
<asp:Parameter Name="supplierID" Type="Int32" />
<asp:Parameter Name="categoryID" Type="Int32" />
<asp:Parameter Name="quantityPerUnit" Type="String" />
<asp:Parameter Name="unitPrice" Type="Decimal" />
<asp:Parameter Name="unitsInStock" Type="Int16" />
<asp:Parameter Name="unitsOnOrder" Type="Int16" />
<asp:Parameter Name="reorderLevel" Type="Int16" />
<asp:Parameter Name="discontinued" Type="Boolean" />
</InsertParameters>
</asp:ObjectDataSource>
O ObjectDataSource inclui um parâmetro para cada um dos parâmetros de entrada para os seus métodos associados, tal como uma lista de SelectParameter está presente quando o ObjectDataSource é configurado para chamar um método select que espera um parâmetro de entrada, tal como GetProductsByCategoryID(categoryID). Como veremos em breve, os valores para DeleteParameters, UpdateParameters e InsertParameters são definidos automaticamente pelo GridView, DetailsView e FormView antes de invocar o método Insert(), Update() ou Delete() de ObjectDataSource. Esses valores também podem ser definidos programaticamente conforme necessário, como discutiremos em um tutorial futuro.
Um efeito colateral do uso do assistente para configurar o ObjectDataSource é que o Visual Studio configura a propriedade OldValuesParameterFormatString como original_{0}. Esse valor de propriedade é usado para incluir os valores originais dos dados que estão sendo editados e é útil em dois cenários:
- Se, ao editar um registro, os usuários puderem alterar o valor da chave primária. Nesse caso, tanto o novo valor da chave primária quanto o valor da chave primária original devem ser fornecidos para que o registro com o valor da chave primária original possa ser encontrado e tenha seu valor atualizado de acordo.
- Ao usar concorrência otimista. A simultaneidade otimista é uma técnica para garantir que dois usuários simultâneos não substituam as alterações um do outro, e é o tópico para um tutorial futuro.
A OldValuesParameterFormatString propriedade indica o nome dos parâmetros de entrada nos métodos de atualização e exclusão do objeto subjacente para os valores originais. Discutiremos esta propriedade e o seu propósito com mais detalhes quando explorarmos a concorrência otimista. Menciono isto agora, no entanto, porque os métodos da nossa BLL não esperam os valores originais e, portanto, é importante que removamos essa propriedade. Deixar a propriedade OldValuesParameterFormatString definida para qualquer coisa diferente do padrão ({0}) causará um erro quando um controle da Web de dados tentar invocar os métodos Update() ou Delete() do ObjectDataSource, porque o ObjectDataSource tentará passar tanto os UpdateParameters ou DeleteParameters especificados quanto os parâmetros de valor original.
Se isso não estiver muito claro neste momento, não se preocupe, examinaremos essa propriedade e sua utilidade em um tutorial futuro. Por enquanto, certifique-se de remover totalmente essa declaração de propriedade da sintaxe declarativa ou definir o valor como o valor padrão ({0}).
Observação
Se simplesmente limpar o valor da propriedade OldValuesParameterFormatString na janela Propriedades no modo de exibição de Design, a propriedade ainda existirá na sintaxe declarativa, mas será definida como uma string vazia. Isso, infelizmente, ainda resultará no mesmo problema discutido acima. Portanto, remova a propriedade completamente da sintaxe declarativa ou, na janela Propriedades, defina o valor como padrão, {0}.
Etapa 3: Adicionando um controle da Web de dados e configurando-o para modificação de dados
Depois que o ObjectDataSource tiver sido adicionado à página e configurado, estaremos prontos para adicionar controles da Web de dados à página para exibir os dados e fornecer um meio para o usuário final modificá-los. Examinaremos o GridView, o DetailsView e o FormView separadamente, pois esses controles da Web de dados diferem em seus recursos e configuração de modificação de dados.
Como veremos no restante deste artigo, adicionar suporte muito básico para edição, inserção e exclusão por meio dos controles GridView, DetailsView e FormView é realmente tão simples quanto marcar algumas caixas de seleção. Há muitas sutilezas e casos extremos no mundo real que tornam o fornecimento de tal funcionalidade mais complexo do que apenas apontar e clicar. Este tutorial, no entanto, se concentra apenas em provar recursos simplistas de modificação de dados. Tutoriais futuros examinarão preocupações que, sem dúvida, surgirão em um cenário do mundo real.
Excluindo dados do GridView
Comece arrastando um GridView da Caixa de Ferramentas para o Designer. Em seguida, vincule o ObjectDataSource ao GridView selecionando-o na lista suspensa na tag inteligente do GridView. Neste ponto, a marcação declarativa do GridView será:
<asp:GridView ID="GridView1" runat="server" AutoGenerateColumns="False"
DataKeyNames="ProductID" DataSourceID="ObjectDataSource1">
<Columns>
<asp:BoundField DataField="ProductID" HeaderText="ProductID"
InsertVisible="False"
ReadOnly="True" SortExpression="ProductID" />
<asp:BoundField DataField="ProductName" HeaderText="ProductName"
SortExpression="ProductName" />
<asp:BoundField DataField="SupplierID" HeaderText="SupplierID"
SortExpression="SupplierID" />
<asp:BoundField DataField="CategoryID" HeaderText="CategoryID"
SortExpression="CategoryID" />
<asp:BoundField DataField="QuantityPerUnit"
HeaderText="QuantityPerUnit"
SortExpression="QuantityPerUnit" />
<asp:BoundField DataField="UnitPrice" HeaderText="UnitPrice"
SortExpression="UnitPrice" />
<asp:BoundField DataField="UnitsInStock"
HeaderText="UnitsInStock" SortExpression="UnitsInStock" />
<asp:BoundField DataField="UnitsOnOrder"
HeaderText="UnitsOnOrder" SortExpression="UnitsOnOrder" />
<asp:BoundField DataField="ReorderLevel"
HeaderText="ReorderLevel" SortExpression="ReorderLevel" />
<asp:CheckBoxField DataField="Discontinued"
HeaderText="Discontinued" SortExpression="Discontinued" />
<asp:BoundField DataField="CategoryName"
HeaderText="CategoryName" ReadOnly="True"
SortExpression="CategoryName" />
<asp:BoundField DataField="SupplierName"
HeaderText="SupplierName" ReadOnly="True"
SortExpression="SupplierName" />
</Columns>
</asp:GridView>
Vincular o GridView ao ObjectDataSource por meio de sua marca inteligente tem dois benefícios:
- BoundFields e CheckBoxFields são criados automaticamente para cada um dos campos retornados pelo ObjectDataSource. Além disso, as propriedades de BoundField e CheckBoxField são definidas com base nos metadados do campo subjacente. Por exemplo, os campos
ProductID,CategoryNameeSupplierNameestão marcados como somente leitura noProductsDataTablee, portanto, não devem ser editáveis durante a edição. Para acomodar isso, essas propriedades ReadOnly de BoundFields são definidas comotrue. - A propriedade DataKeyNames é atribuída ao(s) campo(s) de chave primária do objeto subjacente. Isso é essencial ao usar o GridView para editar ou excluir dados, pois essa propriedade indica o campo (ou conjunto de campos) que identifica exclusivamente cada registro. Para obter mais informações sobre a
DataKeyNamespropriedade, consulte o tutorial Master/Detail Using a Selectable Master GridView with a Details DetailView .
Embora o GridView possa ser vinculado ao ObjectDataSource por meio da janela de Propriedades ou da sintaxe declarativa, isso requer que você adicione manualmente o BoundField e a marcação DataKeyNames apropriada.
O controle GridView fornece suporte interno para edição e exclusão em nível de linha. Configurar um GridView para suportar a exclusão adiciona uma coluna de botões Delete. Quando o usuário final clica no botão Excluir para uma linha específica, um postback ocorre e o GridView executa as seguintes etapas:
- Os valores de ObjectDataSource
DeleteParameterssão atribuídos - O método de
Delete()ObjectDataSource é invocado, excluindo o registro especificado - O GridView se religa ao ObjectDataSource invocando seu
Select()método
Os valores atribuídos ao DeleteParameters são os valores do(s) campo(s) DataKeyNames para a linha em que o botão Apagar foi clicado. Portanto, é vital que a DataKeyNames propriedade de um GridView seja definida corretamente. Se estiver ausente, será atribuído ao DeleteParameters um valor null na Etapa 1, que, por sua vez, não resultará em nenhum registro excluído na Etapa 2.
Observação
A DataKeys coleção é armazenada no estado de controlo do GridView, o que significa que os DataKeys valores serão lembrados durante um postback, mesmo que o estado da vista do GridView tenha sido desativado. No entanto, é muito importante que o estado de exibição permaneça habilitado para GridViews que oferecem suporte à edição ou exclusão (o comportamento padrão). Se você definir a propriedade s EnableViewState de GridView como false, o comportamento de edição e exclusão funcionará bem para um único usuário, mas se houver usuários simultâneos excluindo dados, existe a possibilidade de que esses usuários simultâneos possam excluir ou editar acidentalmente registros que não pretendiam.
Esse mesmo aviso também se aplica a DetailsViews e FormViews.
Para adicionar funcionalidades de eliminação a um GridView, basta ir à sua etiqueta inteligente e marcar a caixa de seleção Ativar eliminação.
Figura 10: Marque a caixa de verificação para ativar a eliminação
Marcar a caixa de seleção Ativar eliminação na etiqueta inteligente adiciona um CommandField ao GridView. O CommandField renderiza uma coluna no GridView com botões para executar uma ou mais das seguintes tarefas: selecionar um registro, editar um registro e excluir um registro. Vimos anteriormente o CommandField em ação ao selecionar registos no tutorial Master/Detail Usando um GridView Mestre selecionável com um DetailView de Detalhes.
O CommandField contém várias ShowXButton propriedades que indicam qual série de botões são exibidos no CommandField. Ao selecionar a caixa de seleção Ativar eliminação, um CommandField cuja propriedade ShowDeleteButton é true foi adicionado à coleção Columns do GridView.
<asp:GridView ID="GridView1" runat="server" AutoGenerateColumns="False"
DataKeyNames="ProductID" DataSourceID="ObjectDataSource1">
<Columns>
<asp:CommandField ShowDeleteButton="True" />
... BoundFields removed for brevity ...
</Columns>
</asp:GridView>
Neste ponto, acredite ou não, terminamos de adicionar suporte de exclusão ao GridView! Como mostra a Figura 11, ao visitar esta página através de um navegador, uma coluna de botões Delete está presente.
Figura 11: O CommandField adiciona uma coluna de botões de exclusão (Clique para visualizar a imagem em tamanho real)
Se você estiver criando este tutorial do zero por conta própria, ao testar esta página, clicar no botão Excluir gerará uma exceção. Continue lendo para saber por que essas exceções foram levantadas e como corrigi-las.
Observação
Se você estiver acompanhando usando o download que acompanha este tutorial, esses problemas já foram contabilizados. No entanto, encorajo você a ler os detalhes listados abaixo para ajudar a identificar problemas que possam surgir e soluções adequadas.
Se, ao tentar excluir um produto, você receber uma exceção cuja mensagem é semelhante a "ObjectDataSource 'ObjectDataSource1' não pôde encontrar um método não genérico 'DeleteProduct' que tenha parâmetros: productID, original_ProductID", você provavelmente esqueceu de remover a OldValuesParameterFormatString propriedade do ObjectDataSource. Com a propriedade OldValuesParameterFormatString especificada, o ObjectDataSource tenta passar as entradas productID e original_ProductID para o método DeleteProduct.
DeleteProduct, no entanto, só aceita um único parâmetro de entrada, daí a exceção. Remover a OldValuesParameterFormatString propriedade (ou defini-la como {0}) instrui o ObjectDataSource a não tentar passar o parâmetro de entrada original.
Figura 12: Verifique se a propriedade foi limpa (OldValuesParameterFormatString imagem em tamanho real)
Mesmo que você tenha removido a OldValuesParameterFormatString propriedade, você ainda receberá uma exceção ao tentar excluir um produto com a mensagem: "A instrução DELETE entrou em conflito com a restrição REFERENCE 'FK_Order_Details_Products'." O banco de dados Northwind contém uma restrição de chave estrangeira entre a Order Details tabela e Products , o que significa que um produto não pode ser excluído do sistema se houver um ou mais registros para ele na Order Details tabela. Como cada produto no banco de dados Northwind tem pelo menos um registro no Order Details, não podemos excluir nenhum produto até que primeiro excluamos os registros de detalhes do pedido associados ao produto.
Figura 13: Uma restrição de chave estrangeira proíbe a exclusão de produtos (Clique para visualizar a imagem em tamanho real)
Para o nosso tutorial, vamos apenas excluir todos os registros da Order Details tabela. Em um aplicativo do mundo real, precisaríamos:
- Ter outra tela para gerenciar as informações de detalhes do pedido
- Aumentar o método
DeleteProductpara incluir lógica para eliminar os detalhes do pedido do produto especificado - Modifique a consulta SQL usada pelo TableAdapter para incluir a exclusão dos detalhes do pedido do produto especificado
Vamos simplesmente apagar todos os registos da tabela Order Details para contornar a restrição de chave estrangeira. Vá para o Explorador de Servidores no Visual Studio, clique com o botão direito no nó NORTHWND.MDF e escolha Nova Consulta. Em seguida, na janela de consulta, execute a seguinte instrução SQL: DELETE FROM [Order Details]
Figura 14: Excluir todos os registros da tabela (Order Details imagem em tamanho real)
Depois de limpar a Order Details tabela, clicar no botão Excluir excluirá o produto sem erro. Se ao clicar no botão Apagar o produto não for excluído, verifique se a propriedade do GridView DataKeyNames está definida como o campo de chave primária ProductID.
Observação
Ao clicar no botão Eliminar, ocorre um retorno ao servidor e o registo é eliminado. Isso pode ser perigoso, pois é fácil clicar acidentalmente no botão Apagar da linha errada. Em um tutorial futuro, veremos como adicionar uma confirmação do lado do cliente ao excluir um registro.
Editando dados com o GridView
Junto com a exclusão, o controle GridView também fornece suporte interno de edição em nível de linha. Configurar um GridView para suportar a edição adiciona uma coluna de botões Editar. Do ponto de vista do usuário final, clicar no botão Editar de uma linha faz com que essa linha se torne editável, transformando as células em caixas de texto contendo os valores existentes e substituindo o botão Editar pelos botões Atualizar e Cancelar. Depois de fazer as alterações desejadas, o usuário final pode clicar no botão Atualizar para confirmar as alterações ou no botão Cancelar para descartá-las. Em ambos os casos, depois de clicar em Atualizar ou Cancelar, o GridView retorna ao seu estado de pré-edição.
Do nosso ponto de vista como desenvolvedor da página, quando o usuário final clica no botão Editar para uma linha específica, um postback ocorre e o GridView executa as seguintes etapas:
- A propriedade
EditItemIndexdo GridView é atribuída ao índice da linha cujo botão Editar foi clicado - O GridView se religa ao ObjectDataSource invocando seu
Select()método - O índice de linha que corresponde ao
EditItemIndexé processado em "modo de edição". Nesse modo, o botão Editar é substituído pelos botões Atualizar e Cancelar, e campos BoundFields, cujas propriedadesReadOnlysão False (por padrão), são renderizados como controles da Web TextBox, cujas propriedadesTextsão atribuídas aos valores dos campos de dados.
Neste ponto, a marcação é retornada ao navegador, permitindo que o usuário final faça quaisquer alterações nos dados da linha. Quando o usuário clica no botão Atualizar, ocorre um postback e o GridView executa as seguintes etapas:
- Os valores de
UpdateParametersdo ObjectDataSource são atribuídos aos valores inseridos pelo utilizador na interface de edição do GridView. - O método do
Update()ObjectDataSource é invocado, atualizando o registro especificado - O GridView se religa ao ObjectDataSource invocando seu
Select()método
Os valores de chave primária atribuídos à UpdateParameters na Etapa 1 vêm dos valores especificados na DataKeyNames propriedade, enquanto os valores de chave não primária vêm do texto nos controles da Web TextBox para a linha editada. Assim como acontece com a exclusão, é vital que a DataKeyNames propriedade de um GridView seja definida corretamente. Se estiver em falta, ao valor da chave primária UpdateParameters será atribuído um valor null na Etapa 1, o que, por sua vez, não resultará na atualização de nenhum registo na Etapa 2.
A funcionalidade de edição pode ser ativada simplesmente marcando a caixa de seleção Ativar edição na marca inteligente do GridView.
Figura 15: Marque a caixa de seleção Ativar edição
Marcar a caixa de seleção Permitir edição adicionará um CommandField (se necessário) e definirá sua ShowEditButton propriedade como true. Como vimos anteriormente, o CommandField contém várias ShowXButton propriedades que indicam qual série de botões são exibidos no CommandField. Marcar a caixa de seleção Ativar edição adiciona a propriedade ShowEditButton ao CommandField existente.
<asp:GridView ID="GridView1" runat="server" AutoGenerateColumns="False"
DataKeyNames="ProductID" DataSourceID="ObjectDataSource1">
<Columns>
<asp:CommandField ShowDeleteButton="True"
ShowEditButton="True" />
... BoundFields removed for brevity ...
</Columns>
</asp:GridView>
Basta isso para adicionar suporte rudimentar de edição. Como mostra a Figura 16, a interface de edição é bastante bruta cada BoundField cuja ReadOnly propriedade está definida como false (o padrão) é renderizada como uma TextBox. Isso inclui campos como CategoryID e SupplierID, que são chaves para outras tabelas.
Figura 16: Clicar no botão de edição de Chai exibe a linha no modo de edição (Clique para visualizar a imagem em tamanho real)
Além de pedir aos utilizadores para editarem diretamente os valores de chave estrangeira, a interface de edição apresenta as seguintes deficiências:
- Se o usuário inserir um
CategoryIDouSupplierIDque não existe no banco de dados, oUPDATEviolará uma restrição de chave estrangeira, fazendo com que uma exceção seja gerada. - A interface de edição não inclui qualquer validação. Se você não fornecer um valor necessário (como
ProductName), ou inserir um valor de cadeia de caracteres onde um valor numérico é esperado (como inserir "Demais!" na caixa deUnitPricetexto), uma exceção será lançada. Um tutorial futuro examinará como adicionar controles de validação à interface do usuário de edição. - Atualmente, todos os campos do produto que não sejam somente leitura têm de ser incluídos no GridView. Se removêssemos um campo do GridView, como, por exemplo,
UnitPrice, ao atualizar os dados, o GridView não definiria o valor necessário, o que alteraria o campoUnitPricedo registo na base de dados para um valorUpdateParameters. Da mesma forma, se um campo obrigatório, comoProductName, for removido do GridView, a atualização falhará com a mesma exceção "Coluna 'ProductName' não permite nulos" mencionada acima. - A formatação da interface de edição deixa muito a desejar. O
UnitPriceé mostrado com quatro casas decimais. Idealmente, osCategoryIDvalores eSupplierIDconteriam DropDownLists que listam as categorias e fornecedores no sistema.
Todas essas são deficiências com as quais teremos que conviver por enquanto, mas que serão abordadas em tutoriais futuros.
Inserindo, editando e excluindo dados com o DetailsView
Como vimos em tutoriais anteriores, o controle DetailsView exibe um registro de cada vez e, como o GridView, permite editar e excluir o registro exibido no momento. A experiência do usuário final com a edição e exclusão de itens de um DetailsView e o fluxo de trabalho do lado ASP.NET é idêntica à do GridView. Onde o DetailsView difere do GridView é que ele também fornece suporte de inserção interno.
Para demonstrar os recursos de modificação de dados do GridView, comece adicionando um DetailsView à Basics.aspx página acima do GridView existente e associe-o ao ObjectDataSource existente por meio da marca inteligente do DetailsView. Em seguida, remova as propriedades Height e Width do DetailsView e marque a opção Ativar paginação a partir da marca inteligente. Para ativar suporte à edição, inserção e exclusão, basta marcar as caixas de seleção Ativar edição, Ativar inserção e Ativar exclusão na etiqueta inteligente.
Figura 17: Configurar o DetailsView para dar suporte à edição, inserção e exclusão
Assim como acontece com o GridView, adicionar suporte a edição, inserção ou exclusão adiciona um CommandField ao DetailsView, como mostra a sintaxe declarativa a seguir:
<asp:DetailsView ID="DetailsView1" runat="server" AutoGenerateRows="False"
DataKeyNames="ProductID" DataSourceID="ObjectDataSource1" AllowPaging="True">
<Fields>
<asp:BoundField DataField="ProductID"
HeaderText="ProductID" InsertVisible="False"
ReadOnly="True" SortExpression="ProductID" />
<asp:BoundField DataField="ProductName"
HeaderText="ProductName" SortExpression="ProductName" />
<asp:BoundField DataField="SupplierID" HeaderText="SupplierID"
SortExpression="SupplierID" />
<asp:BoundField DataField="CategoryID" HeaderText="CategoryID"
SortExpression="CategoryID" />
<asp:BoundField DataField="QuantityPerUnit"
HeaderText="QuantityPerUnit"
SortExpression="QuantityPerUnit" />
<asp:BoundField DataField="UnitPrice"
HeaderText="UnitPrice" SortExpression="UnitPrice" />
<asp:BoundField DataField="UnitsInStock"
HeaderText="UnitsInStock" SortExpression="UnitsInStock" />
<asp:BoundField DataField="UnitsOnOrder"
HeaderText="UnitsOnOrder" SortExpression="UnitsOnOrder" />
<asp:BoundField DataField="ReorderLevel"
HeaderText="ReorderLevel" SortExpression="ReorderLevel" />
<asp:CheckBoxField DataField="Discontinued"
HeaderText="Discontinued" SortExpression="Discontinued" />
<asp:BoundField DataField="CategoryName"
HeaderText="CategoryName" ReadOnly="True"
SortExpression="CategoryName" />
<asp:BoundField DataField="SupplierName"
HeaderText="SupplierName" ReadOnly="True"
SortExpression="SupplierName" />
<asp:CommandField ShowDeleteButton="True"
ShowEditButton="True" ShowInsertButton="True" />
</Fields>
</asp:DetailsView>
Observe que, para o DetailsView, o CommandField aparece no final da coleção Columns por padrão. Como os campos do DetailsView são renderizados como linhas, o CommandField aparece como uma linha com os botões Inserir, Editar e Excluir na parte inferior do DetailsView.
Figura 18: Configurar o DetailsView para suportar edição, inserção e exclusão (Clique para visualizar a imagem em tamanho real)
Clicar no botão Excluir inicia a mesma sequência de eventos que o GridView: um postback; seguido pelo DetailsView preenchendo seu ObjectDataSource com base nos valores de DeleteParameters; e concluído com a chamada do método DataKeyNames do seu ObjectDataSource, que realmente remove o produto do banco de dados. A edição no DetailsView também funciona de forma idêntica à do GridView.
Para inserir, o usuário final recebe um botão Novo que, quando clicado, renderiza o DetailsView em "modo de inserção". Com "modo de inserção", o botão Novo é substituído pelos botões Inserir e Cancelar e apenas os BoundFields cuja InsertVisible propriedade está definida como true (o padrão) são exibidos. Esses campos de dados identificados como campos de incremento automático, como ProductID, têm sua propriedade InsertVisible definida como false ao vincular o DetailsView à fonte de dados por meio da marca inteligente.
Ao vincular uma fonte de dados a um DetailsView por meio da marca inteligente, o Visual Studio define a InsertVisible propriedade como false somente para campos de incremento automático. Os campos somente leitura, como CategoryName e SupplierName, serão exibidos na interface do usuário do "modo de inserção", a menos que sua InsertVisible propriedade esteja explicitamente definida como false. Tire um momento para definir as propriedades desses dois campos InsertVisible como false, através da sintaxe declarativa do DetailsView ou através do link Editar Campos na etiqueta inteligente. Na Figura 19, configura-se as propriedades InsertVisible para false ao clicar no link Editar Campos.
Figura 19: Northwind Traders agora oferece chá Acme (Clique para ver a imagem em tamanho real)
Depois de definir as InsertVisible propriedades, visualize a Basics.aspx página num navegador e clique no botão Novo. A Figura 20 mostra o DetailsView ao adicionar uma nova bebida, Acme Tea, à nossa linha de produtos.
Figura 20: Northwind Traders agora oferece chá Acme (Clique para ver a imagem em tamanho real)
Depois de inserir os detalhes do Acme Tea e clicar no botão Inserir, ocorre um postback e o novo registo é adicionado à tabela do Products banco de dados. Como este DetailsView lista os produtos em ordem com os quais eles existem na tabela do banco de dados, devemos acessar o último produto para ver o novo produto.
Figura 21: Detalhes do Acme Tea (Clique para visualizar a imagem em tamanho real)
Observação
A propriedade CurrentMode de DetailsView indica a interface que está sendo exibida e pode ser um dos seguintes valores: Edit, Insert, ou ReadOnly. A propriedade DefaultMode indica o modo ao qual DetailsView retorna após a conclusão de uma edição ou inserção e é útil para exibir um DetailsView que está permanentemente no modo de edição ou inserção.
Os recursos de inserção e edição de apontar e clicar do DetailsView sofrem das mesmas limitações que o GridView: o utilizador deve inserir valores CategoryID e SupplierID existentes através de uma caixa de texto; a interface não tem qualquer lógica de validação; todos os campos do produto que não permitem valores NULL ou não têm um valor padrão especificado ao nível da base de dados, devem ser incluídos na interface de inserção, etc.
As técnicas que examinaremos para estender e melhorar a interface de edição do GridView em artigos futuros também podem ser aplicadas às interfaces de edição e inserção do controle DetailsView.
Usando o FormView para uma interface de usuário de modificação de dados mais flexível
O FormView oferece suporte interno para inserir, editar e excluir dados, mas como ele usa modelos em vez de campos, não há lugar para adicionar o BoundFields ou o CommandField usado pelos controles GridView e DetailsView para fornecer a interface de modificação de dados. Em vez disso, a interface da Web para coletar entrada do utilizador ao adicionar um novo item ou editar um existente, junto com os botões Novo, Editar, Excluir, Inserir, Atualizar e Cancelar, deve ser adicionada manualmente aos modelos apropriados. Felizmente, o Visual Studio criará automaticamente a interface necessária ao ligar o FormView a uma fonte de dados por meio da lista suspensa na sua etiqueta inteligente.
Para ilustrar essas técnicas, comece adicionando um FormView à Basics.aspx página e, a partir da marca inteligente do FormView, vincule-o ao ObjectDataSource já criado. Isso gerará um EditItemTemplate, InsertItemTemplatee ItemTemplate para os controles FormView com TextBox Web para coletar a entrada do usuário e controles Button Web para os botões Novo, Editar, Excluir, Inserir, Atualizar e Cancelar. Além disso, a propriedade DataKeyNames do FormView é definida para o campo de chave primária (ProductID) do objeto retornado pelo ObjectDataSource. Por fim, marque a opção Ativar Paginação na etiqueta inteligente do FormView.
A seguir mostra a marcação declarativa para o FormView ItemTemplate após o FormView ter sido vinculado ao ObjectDataSource. Por padrão, cada campo de produto de valor não-booleano é vinculado à Text propriedade de um controle Web de rótulo, enquanto cada campo de valor booleano (Discontinued) está vinculado à Checked propriedade de um controle Web CheckBox desabilitado. Para que os botões Novo, Editar e Excluir acionem determinado comportamento do FormView quando clicados, é imperativo que seus CommandName valores sejam definidos como New, Edite Delete, respectivamente.
<asp:FormView ID="FormView1" runat="server" DataKeyNames="ProductID"
DataSourceID="ObjectDataSource1" AllowPaging="True">
<EditItemTemplate>
...
</EditItemTemplate>
<InsertItemTemplate>
...
</InsertItemTemplate>
<ItemTemplate>
ProductID:
<asp:Label ID="ProductIDLabel" runat="server"
Text='<%# Eval("ProductID") %>'></asp:Label><br />
ProductName:
<asp:Label ID="ProductNameLabel" runat="server"
Text='<%# Bind("ProductName") %>'>
</asp:Label><br />
SupplierID:
<asp:Label ID="SupplierIDLabel" runat="server"
Text='<%# Bind("SupplierID") %>'>
</asp:Label><br />
CategoryID:
<asp:Label ID="CategoryIDLabel" runat="server"
Text='<%# Bind("CategoryID") %>'>
</asp:Label><br />
QuantityPerUnit:
<asp:Label ID="QuantityPerUnitLabel" runat="server"
Text='<%# Bind("QuantityPerUnit") %>'>
</asp:Label><br />
UnitPrice:
<asp:Label ID="UnitPriceLabel" runat="server"
Text='<%# Bind("UnitPrice") %>'></asp:Label><br />
UnitsInStock:
<asp:Label ID="UnitsInStockLabel" runat="server"
Text='<%# Bind("UnitsInStock") %>'>
</asp:Label><br />
UnitsOnOrder:
<asp:Label ID="UnitsOnOrderLabel" runat="server"
Text='<%# Bind("UnitsOnOrder") %>'>
</asp:Label><br />
ReorderLevel:
<asp:Label ID="ReorderLevelLabel" runat="server"
Text='<%# Bind("ReorderLevel") %>'>
</asp:Label><br />
Discontinued:
<asp:CheckBox ID="DiscontinuedCheckBox" runat="server"
Checked='<%# Bind("Discontinued") %>'
Enabled="false" /><br />
CategoryName:
<asp:Label ID="CategoryNameLabel" runat="server"
Text='<%# Bind("CategoryName") %>'>
</asp:Label><br />
SupplierName:
<asp:Label ID="SupplierNameLabel" runat="server"
Text='<%# Bind("SupplierName") %>'>
</asp:Label><br />
<asp:LinkButton ID="EditButton" runat="server"
CausesValidation="False" CommandName="Edit"
Text="Edit">
</asp:LinkButton>
<asp:LinkButton ID="DeleteButton" runat="server"
CausesValidation="False" CommandName="Delete"
Text="Delete">
</asp:LinkButton>
<asp:LinkButton ID="NewButton" runat="server"
CausesValidation="False" CommandName="New"
Text="New">
</asp:LinkButton>
</ItemTemplate>
</asp:FormView>
A Figura 22 mostra o ItemTemplate do FormView quando visualizado através de um navegador. Cada campo de produto é listado com os botões Novo, Editar e Excluir na parte inferior.
Figura 22: O Defaut FormView ItemTemplate lista cada campo de produto junto com os botões Novo, Editar e Excluir (Clique para visualizar a imagem em tamanho real)
Como com o GridView e DetailsView, clicar no botão Eliminar ou em qualquer outro Button, LinkButton ou ImageButton cuja propriedade CommandName esteja definida como Delete causa um postback, preenche o DeleteParameters do ObjectDataSource com base no valor do DataKeyNames do FormView e invoca o método do Delete() do ObjectDataSource.
Quando o botão Editar é clicado, um postback ocorre e os dados são redirecionados para o EditItemTemplate, que é responsável por renderizar a interface de edição. Essa interface inclui os controles da Web para edição de dados, juntamente com os botões Atualizar e Cancelar. O padrão EditItemTemplate gerado pelo Visual Studio contém um Label para qualquer campo de incremento automático (ProductID), um TextBox para cada campo de valor não booleano e um CheckBox para cada campo de valor booleano. Este comportamento é muito semelhante aos BoundFields gerados automaticamente nos controles GridView e DetailsView.
Observação
Um pequeno problema com a geração automática do EditItemTemplate FormView é que ele exibe controlos Web TextBox para os campos que são somente leitura, como CategoryName e SupplierName. Veremos como explicar isso em breve.
Os controles TextBox no EditItemTemplate têm sua Text propriedade vinculada ao valor de seu campo de dados correspondente usando vinculação de dados bidirecional. A vinculação de dados bidirecional, indicada por <%# Bind("dataField") %>, executa a vinculação de dados ao vincular dados ao modelo e ao preencher os parâmetros do ObjectDataSource para inserir ou editar registros. Ou seja, quando o usuário clica no botão Editar do ItemTemplate, o Bind() método retorna o valor do campo de dados especificado. Depois que o usuário faz suas alterações e clica em Atualizar, os valores postados de volta que correspondem aos campos de dados especificados usando Bind() são aplicados ao ObjectDataSource's UpdateParameters. Como alternativa, a vinculação de dados unidirecional, indicada por <%# Eval("dataField") %>, só recupera os valores do campo de dados ao vincular dados ao modelo e não retorna os valores inseridos pelo usuário aos parâmetros da fonte de dados no postback.
A marcação declarativa a seguir mostra o FormView's EditItemTemplate. Observe que o Bind() método é usado na sintaxe de vinculação de dados aqui e que os controles da Web Update and Cancel Button têm suas CommandName propriedades definidas de acordo.
<asp:FormView ID="FormView1" runat="server" DataKeyNames="ProductID"
DataSourceID="ObjectDataSource1" AllowPaging="True">
<EditItemTemplate>
ProductID:
<asp:Label ID="ProductIDLabel1" runat="server"
Text="<%# Eval("ProductID") %>"></asp:Label><br />
ProductName:
<asp:TextBox ID="ProductNameTextBox" runat="server"
Text="<%# Bind("ProductName") %>">
</asp:TextBox><br />
SupplierID:
<asp:TextBox ID="SupplierIDTextBox" runat="server"
Text="<%# Bind("SupplierID") %>">
</asp:TextBox><br />
CategoryID:
<asp:TextBox ID="CategoryIDTextBox" runat="server"
Text="<%# Bind("CategoryID") %>">
</asp:TextBox><br />
QuantityPerUnit:
<asp:TextBox ID="QuantityPerUnitTextBox" runat="server"
Text="<%# Bind("QuantityPerUnit") %>">
</asp:TextBox><br />
UnitPrice:
<asp:TextBox ID="UnitPriceTextBox" runat="server"
Text="<%# Bind("UnitPrice") %>">
</asp:TextBox><br />
UnitsInStock:
<asp:TextBox ID="UnitsInStockTextBox" runat="server"
Text="<%# Bind("UnitsInStock") %>">
</asp:TextBox><br />
UnitsOnOrder:
<asp:TextBox ID="UnitsOnOrderTextBox" runat="server"
Text="<%# Bind("UnitsOnOrder") %>">
</asp:TextBox><br />
ReorderLevel:
<asp:TextBox ID="ReorderLevelTextBox" runat="server"
Text="<%# Bind("ReorderLevel") %>">
</asp:TextBox><br />
Discontinued:
<asp:CheckBox ID="DiscontinuedCheckBox" runat="server"
Checked="<%# Bind("Discontinued") %>" /><br />
CategoryName:
<asp:TextBox ID="CategoryNameTextBox" runat="server"
Text="<%# Bind("CategoryName") %>">
</asp:TextBox><br />
SupplierName:
<asp:TextBox ID="SupplierNameTextBox" runat="server"
Text="<%# Bind("SupplierName") %>">
</asp:TextBox><br />
<asp:LinkButton ID="UpdateButton" runat="server"
CausesValidation="True" CommandName="Update"
Text="Update">
</asp:LinkButton>
<asp:LinkButton ID="UpdateCancelButton" runat="server"
CausesValidation="False" CommandName="Cancel"
Text="Cancel">
</asp:LinkButton>
</EditItemTemplate>
<InsertItemTemplate>
...
</InsertItemTemplate>
<ItemTemplate>
...
</ItemTemplate>
</asp:FormView>
O nosso EditItemTemplate, neste ponto, fará com que uma exceção seja lançada se tentarmos usá-la. O problema é que os CategoryName campos e SupplierName são renderizados como controles da Web TextBox no EditItemTemplate. Precisamos alterar essas TextBoxes para Labels ou removê-las completamente. Vamos simplesmente excluí-los totalmente do EditItemTemplate.
A Figura 23 mostra o FormView em um navegador depois que o botão Edit foi clicado para Chai. Observe que os campos SupplierName e CategoryName mostrados no ItemTemplate não estão mais presentes, pois acabamos de removê-los do EditItemTemplate. Quando o botão Atualizar é clicado, o FormView prossegue pela mesma sequência de etapas que os controles GridView e DetailsView.
Figura 23: Por padrão, o campo mostra cada produto editável como uma caixa de texto ou caixa de seleção (EditItemTemplate imagem em tamanho real)
Quando o botão Inserir é clicado, ocorre um postback do ItemTemplate FormView. No entanto, nenhum dado é vinculado ao FormView porque um novo registro está sendo adicionado. A InsertItemTemplate interface inclui os controles da Web para adicionar um novo registro junto com os botões Inserir e Cancelar. O padrão InsertItemTemplate gerado pelo Visual Studio contém um TextBox para cada campo de valor não-booleano e um CheckBox para cada campo de valor booleano, semelhante à interface do gerado EditItemTemplateautomaticamente. Os controles TextBox têm sua Text propriedade vinculada ao valor de seu campo de dados correspondente usando vinculação de dados bidirecional.
A marcação declarativa a seguir mostra o FormView's InsertItemTemplate. Observe que o método Bind() é usado na sintaxe de vinculação de dados aqui e que os botões Web de Inserir e Cancelar têm suas propriedades CommandName definidas adequadamente.
<asp:FormView ID="FormView1" runat="server" DataKeyNames="ProductID"
DataSourceID="ObjectDataSource1" AllowPaging="True">
<EditItemTemplate>
...
</EditItemTemplate>
<InsertItemTemplate>
ProductName:
<asp:TextBox ID="ProductNameTextBox" runat="server"
Text="<%# Bind("ProductName") %>">
</asp:TextBox><br />
SupplierID:
<asp:TextBox ID="SupplierIDTextBox" runat="server"
Text="<%# Bind("SupplierID") %>">
</asp:TextBox><br />
CategoryID:
<asp:TextBox ID="CategoryIDTextBox" runat="server"
Text="<%# Bind("CategoryID") %>">
</asp:TextBox><br />
QuantityPerUnit:
<asp:TextBox ID="QuantityPerUnitTextBox" runat="server"
Text="<%# Bind("QuantityPerUnit") %>">
</asp:TextBox><br />
UnitPrice:
<asp:TextBox ID="UnitPriceTextBox" runat="server"
Text="<%# Bind("UnitPrice") %>">
</asp:TextBox><br />
UnitsInStock:
<asp:TextBox ID="UnitsInStockTextBox" runat="server"
Text="<%# Bind("UnitsInStock") %>">
</asp:TextBox><br />
UnitsOnOrder:
<asp:TextBox ID="UnitsOnOrderTextBox" runat="server"
Text="<%# Bind("UnitsOnOrder") %>">
</asp:TextBox><br />
ReorderLevel:
<asp:TextBox ID="ReorderLevelTextBox" runat="server"
Text="<%# Bind("ReorderLevel") %>">
</asp:TextBox><br />
Discontinued:
<asp:CheckBox ID="DiscontinuedCheckBox" runat="server"
Checked="<%# Bind("Discontinued") %>" /><br />
CategoryName:
<asp:TextBox ID="CategoryNameTextBox" runat="server"
Text="<%# Bind("CategoryName") %>">
</asp:TextBox><br />
SupplierName:
<asp:TextBox ID="SupplierNameTextBox" runat="server"
Text="<%# Bind("SupplierName") %>">
</asp:TextBox><br />
<asp:LinkButton ID="InsertButton" runat="server"
CausesValidation="True" CommandName="Insert"
Text="Insert">
</asp:LinkButton>
<asp:LinkButton ID="InsertCancelButton" runat="server"
CausesValidation="False" CommandName="Cancel"
Text="Cancel">
</asp:LinkButton>
</InsertItemTemplate>
<ItemTemplate>
...
</ItemTemplate>
</asp:FormView>
Existe uma nuance na geração automática do elemento InsertItemTemplate pelo FormView. Especificamente, os controles da Web TextBox são criados mesmo para os campos que são somente leitura, como CategoryName e SupplierName. Como com o EditItemTemplate, precisamos remover essas TextBoxes do InsertItemTemplate.
A Figura 24 mostra o FormView em um navegador ao adicionar um novo produto, o Acme Coffee. Observe que os campos SupplierName e CategoryName mostrados em ItemTemplate já não estão presentes, pois acabámos de removê-los. Quando o botão Inserir é clicado, o FormView prossegue pela mesma sequência de etapas que o controle DetailsView, adicionando um novo registro à Products tabela. A Figura 25 mostra os detalhes do produto Acme Coffee no FormView após sua inserção.
Figura 24: O InsertItemTemplate dita a interface de inserção do FormView (Clique para visualizar a imagem em tamanho real)
Figura 25: Os detalhes do novo produto, Acme Coffee, são exibidos no FormView (Clique para exibir a imagem em tamanho real)
Ao separar as interfaces somente leitura, edição e inserção em três modelos separados, o FormView permite um grau mais fino de controle sobre essas interfaces do que o DetailsView e o GridView.
Observação
Como o DetailsView, a propriedade do CurrentMode FormView indica a interface que está sendo exibida e sua DefaultMode propriedade indica o modo ao qual o FormView retorna após a conclusão de uma edição ou inserção.
Resumo
Neste tutorial, examinamos os conceitos básicos de inserção, edição e exclusão de dados usando GridView, DetailsView e FormView. Todos esses três controles fornecem algum nível de recursos internos de modificação de dados que podem ser utilizados sem escrever uma única linha de código na página ASP.NET graças aos controles da Web de dados e ao ObjectDataSource. No entanto, as técnicas simples de apontar e clicar tornam uma interface de usuário de modificação de dados bastante frágil e ingênua. Para fornecer validação, injetar valores programáticos, lidar graciosamente com exceções, personalizar a interface do usuário e assim por diante, precisaremos confiar em uma série de técnicas que serão discutidas nos próximos tutoriais.
Feliz Programação!
Sobre o Autor
Scott Mitchell, autor de sete livros sobre ASP/ASP.NET e fundador da 4GuysFromRolla.com, trabalha com tecnologias Web da Microsoft desde 1998. Scott trabalha como consultor, formador e escritor independente. Seu último livro é Sams Teach Yourself ASP.NET 2.0 in 24 Hours. Ele pode ser contatado em mitchell@4GuysFromRolla.com.