Uma visão geral da inserção, atualização e exclusão de dados (VB)

por Scott Mitchell

Baixar PDF

Neste tutorial, veremos como mapear os métodos Insert(), Update() e Delete() de um ObjectDataSource para os métodos das classes BLL, bem como como configurar os controles GridView, DetailsView e FormView para fornecer recursos de modificação de dados.

Introdução

Nos últimos vários 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. Normalmente, 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, ele invoca o método objectDataSource Select() , que, por sua vez, invoca um método de nossa BLL (Camada lógica de negócios), que chama um método no TableAdapter da Camada de Acesso a Dados (DAL) apropriado, que, por sua vez, envia uma SELECT consulta para o banco de dados Northwind.

Lembre-se de que quando criamos o TableAdapters no 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 Criando uma camada lógica de negócios , projetamos métodos na BLL que são chamados para esses métodos DAL de modificação de dados.

Além de seu Select() método, o ObjectDataSource também tem Insert()métodos , Update()e Delete() . Assim como o Select() método , esses três métodos podem ser mapeados para métodos em um objeto subjacente. Quando configurados para inserir, atualizar ou excluir dados, os controles GridView, DetailsView e FormView fornecem uma interface do usuário para modificar os dados subjacentes. Essa interface do usuário chama os Insert()métodos , Update()e Delete() do ObjectDataSource, que invocam os métodos associados do objeto subjacente (consulte a Figura 1).

Os métodos Insert(), Update() e Delete() do ObjectDataSource servem como um proxy para a BLL

Figura 1: os métodos , Update()e Delete() do Insert()ObjectDataSource servem como um proxy na BLL (clique para exibir a imagem em tamanho real)

Neste tutorial, veremos como mapear os métodos , Update()e Delete() do Insert()ObjectDataSource para métodos de classes na BLL, bem como como configurar os controles GridView, DetailsView e FormView para fornecer recursos de modificação de dados.

Etapa 1: Criando as páginas da Web Inserir, Atualizar e Excluir Tutoriais

Antes de começarmos a explorar como inserir, atualizar e excluir dados, vamos primeiro levar um momento para criar as páginas ASP.NET em nosso projeto de site que precisaremos para este tutorial e as próximas várias. 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 master:

  • Default.aspx
  • Basics.aspx
  • DataModificationEvents.aspx
  • ErrorHandling.aspx
  • UIValidation.aspx
  • CustomizedUI.aspx
  • OptimisticConcurrency.aspx
  • ConfirmationOnDelete.aspx
  • UserLevelAccess.aspx

Adicionar as páginas de ASP.NET para os Tutoriais do Modification-Related de Dados

Figura 2: Adicionar as páginas de ASP.NET para os Tutoriais do Modification-Related de Dados

Assim como nas outras pastas, Default.aspx na EditInsertDelete pasta listará os tutoriais em sua seção. Lembre-se de que o SectionLevelTutorialListing.ascx Controle de Usuário fornece essa funcionalidade. Portanto, adicione esse Controle de Usuário ao Default.aspx arrastando-o do Gerenciador de Soluções para a exibição Design da página.

Adicione o Controle de Usuário SectionLevelTutorialListing.ascx ao Default.aspx

Figura 3: Adicionar o Controle de SectionLevelTutorialListing.ascx Usuário a Default.aspx (Clique para exibir 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>

Depois de atualizar Web.sitemap, reserve um momento para exibir o site de tutoriais por meio de um navegador. O menu à esquerda agora inclui itens para edição, inserção e exclusão de tutoriais.

O mapa do site agora inclui entradas 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: Adicionar e configurar o controle ObjectDataSource

Como GridView, DetailsView e FormView diferem em seus recursos de modificação de dados e layout, 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 da Caixa de Ferramentas para o Designer e clique no link Configurar Fonte de Dados de sua marca inteligente. 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.

Configurar o ObjectDataSource para usar a classe ProductsBLL

Figura 5: configurar o ObjectDataSource para usar a ProductsBLL classe (clique para exibir a imagem em tamanho real)

Na próxima tela, podemos especificar quais métodos da ProductsBLL classe são mapeados para o ObjectDataSource, Select()Insert(), Update()e Delete() selecionando a guia apropriada e escolhendo o método na lista suspensa. A Figura 6, que já deve parecer familiar, mapeia o método ObjectDataSource Select() para o ProductsBLL método da GetProducts() classe. Os Insert()métodos , Update()e Delete() podem ser configurados selecionando a guia apropriada na lista na parte superior.

Fazer com que ObjectDataSource retorne todos os produtos

Figura 6: Fazer com que ObjectDataSource retorne todos os produtos (clique para exibir a imagem em tamanho real)

Os números 7, 8 e 9 mostram as guias UPDATE, INSERT e DELETE do ObjectDataSource. Configure essas guias para que os Insert()métodos , Update()e Delete() invoquem os ProductsBLL métodos , AddProducte DeleteProduct da UpdateProductclasse, respectivamente.

Mapear o método Update() do ObjectDataSource para o método UpdateProduct da classe ProductBLL

Figura 7: Mapear o método ObjectDataSource Update() para o ProductBLL método da UpdateProduct classe (clique para exibir a imagem em tamanho real)

Mapear o método Insert() do ObjectDataSource para o método AddProduct da classe ProductBLL

Figura 8: Mapear o método ObjectDataSource Insert() para o ProductBLL método Add Product da classe (clique para exibir a imagem em tamanho real)

Mapear o método Delete() do ObjectDataSource para o método DeleteProduct da classe ProductBLL

Figura 9: mapear o método ObjectDataSource Delete() para o ProductBLL método da DeleteProduct classe (clique para exibir a imagem em tamanho real)

Talvez você tenha notado que as listas suspensas nas guias UPDATE, INSERT e DELETE já tinham esses métodos selecionados. Isso é 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 Function DeleteProduct(ByVal productID As Integer) As Boolean End Function

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ê omitir 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 apropriados ProductsBLL sejam mapeados para os métodos , Update()e Delete() do Insert()ObjectDataSource, clique em Concluir para concluir o assistente.

Examinando a marcação do ObjectDataSource

Depois de configurar o ObjectDataSource por meio de seu assistente, vá para o modo de exibição Origem para examinar a marcação declarativa gerada. A <asp:ObjectDataSource> marca especifica o objeto subjacente e os métodos a serem invocados. Além disso, há DeleteParameters, UpdateParameterse InsertParameters que mapeiam para os parâmetros de entrada para os ProductsBLL métodos , UpdateProducte DeleteProduct da AddProductclasse:

<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 seus métodos associados, assim como uma lista de SelectParameter s está presente quando ObjectDataSource é configurado para chamar um método select que espera um parâmetro de entrada (como GetProductsByCategoryID(categoryID)). Como veremos em breve, os valores para esses DeleteParameters, UpdateParameterse InsertParameters são definidos automaticamente pelo método GridView, DetailsView e FormView antes de invocar o método , Update()ou Delete() do Insert()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 define 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 poderão alterar o valor da chave primária. Nesse caso, o novo valor da chave primária e 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 adequadamente.
  • Ao usar simultaneidade otimista. A simultaneidade otimista é uma técnica para garantir que dois usuários simultâneos não substituam as alterações uns dos outros e seja 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 essa propriedade e sua finalidade em mais detalhes quando explorarmos a simultaneidade otimista. No entanto, digo isso agora, porque os métodos da nossa BLL não esperam os valores originais e, portanto, é importante que removamos essa propriedade. Deixar a OldValuesParameterFormatString propriedade definida como qualquer outra coisa que não seja o padrão ({0}) causará um erro quando um controle da Web de dados tentar invocar os métodos do Update() ObjectDataSource ou Delete() porque o ObjectDataSource tentará passar os UpdateParameters parâmetros de valor original ou DeleteParameters especificados.

Se isso não estiver muito claro neste momento, não se preocupe, examinaremos essa propriedade e seu utilitário em um tutorial futuro. Por enquanto, basta ter certeza de remover essa declaração de propriedade inteiramente da sintaxe declarativa ou definir o valor como o valor padrão ({0}).

Observação

Se você simplesmente limpar o OldValuesParameterFormatString valor da propriedade do janela Propriedades na exibição Design, a propriedade ainda existirá na sintaxe declarativa, mas será definida como uma cadeia de caracteres vazia. Isso, infelizmente, ainda resultará no mesmo problema discutido acima. Portanto, remova a propriedade completamente da sintaxe declarativa ou, do janela Propriedades, defina o valor como o padrão, {0}.

Etapa 3: Adicionar um controle da Web de dados e configurá-lo para modificação de dados

Depois que 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 de modificação de dados e configuração.

Como veremos no restante deste artigo, adicionar edição, inserção e exclusão de suporte muito básicas por meio dos controles GridView, DetailsView e FormView é realmente tão simples quanto verificar algumas caixas de seleção. Há muitas sutilezas e casos de borda no mundo real que tornam o fornecimento dessa funcionalidade mais envolvido do que apenas apontar e clicar. Este tutorial, no entanto, se concentra apenas em provar recursos de modificação de dados simplistas. Tutoriais futuros examinarão preocupações que, sem dúvida, surgirão em uma configuração do mundo real.

Excluindo dados do GridView

Comece arrastando um GridView da Caixa de Ferramentas para o Designer. Em seguida, associe ObjectDataSource ao GridView selecionando-o na lista suspensa na marca 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>

Associar 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 ProductIDcampos , CategoryNamee SupplierName são marcados como somente leitura no ProductsDataTable e, portanto, não devem ser atualizáveis ao editar. Para acomodar isso, as propriedades ReadOnly desses BoundFields são definidas Truecomo .
  • A propriedade DataKeyNames é atribuída aos campos 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 cada registro exclusivo. Para obter mais informações sobre a DataKeyNames propriedade, consulte o tutorial Mestre/Detalhe usando um Selectable Master GridView com um tutorial DetailsView .

Embora o GridView possa ser associado ao ObjectDataSource por meio do janela Propriedades ou sintaxe declarativa, isso exige que você adicione manualmente o BoundField e DataKeyNames a marcação apropriados.

O controle GridView fornece suporte interno para edição e exclusão em nível de linha. Configurar um GridView para dar suporte à exclusão adiciona uma coluna de botões Excluir. Quando o usuário final clica no botão Excluir para uma linha específica, um postback é seguido e o GridView executa as seguintes etapas:

  1. Os valores do DeleteParameters ObjectDataSource são atribuídos
  2. O método objectDataSource Delete() é invocado, excluindo o registro especificado
  3. O GridView se vincula novamente ao ObjectDataSource invocando seu Select() método

Os valores atribuídos ao DeleteParameters são os valores dos DataKeyNames campos da linha cujo botão Excluir foi clicado. Portanto, é vital que a propriedade de DataKeyNames um GridView seja definida corretamente. Se ele estiver ausente, o DeleteParameters receberá um valor de Nothing na Etapa 1, o 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 controle GridView, o que significa que os DataKeys valores serão lembrados no postback mesmo que o estado de exibição do GridView tenha sido desabilitado. No entanto, é muito importante que o estado de exibição permaneça habilitado para GridViews que dão suporte à edição ou exclusão (o comportamento padrão). Se você definir a propriedade gridview EnableViewState 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 registros acidentalmente que eles não pretendiam.

Esse mesmo aviso também se aplica a DetailsViews e FormViews.

Para adicionar recursos de exclusão a um GridView, basta acessar sua marca inteligente e marcar caixa de seleção Habilitar Exclusão.

Marque a caixa de seleção Habilitar Exclusão

Figura 10: Marque a caixa de seleção Habilitar Exclusão

Verificar a caixa de seleção Habilitar Exclusão da marca 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. Anteriormente, vimos o CommandField em ação com a seleção de registros no Mestre/Detalhe usando um Selectable Master GridView com um tutorial DetailsView .

O CommandField contém várias ShowXButton propriedades que indicam quais séries de botões são exibidos no CommandField. Ao verificar a caixa de seleção Habilitar Exclusão, um CommandField cuja ShowDeleteButton propriedade é True adicionada à 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 o suporte de exclusão ao GridView! Como mostra a Figura 11, ao visitar esta página por meio de um navegador, uma coluna de botões Excluir está presente.

O CommandField adiciona uma coluna de botões excluir

Figura 11: o campo de comando adiciona uma coluna de botões de exclusão (clique para exibir a imagem em tamanho real)

Se você estiver criando este tutorial do zero por conta própria, ao testar esta página clicando no botão Excluir gerará uma exceção. Continue lendo para saber por que essas exceções foram geradas 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 podem surgir e soluções alternativas adequadas.

Se, ao tentar excluir um produto, você obtém 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 OldValuesParameterFormatString propriedade especificada, o ObjectDataSource tenta passar parâmetros productID de entrada e original_ProductID para o DeleteProduct método . DeleteProduct, no entanto, aceita apenas 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.

Verifique se a propriedade OldValuesParameterFormatString foi desmarcada

Figura 12: Verifique se a OldValuesParameterFormatString propriedade foi desmarcada (clique para exibir a imagem em tamanho real)

Mesmo se você tiver removido a OldValuesParameterFormatString propriedade, 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é excluirmos primeiro os registros de detalhes de pedido associados do produto.

Uma restrição de chave estrangeira proíbe a exclusão de produtos

Figura 13: uma restrição de chave estrangeira proíbe a exclusão de produtos (clique para exibir imagem em tamanho real)

Para nosso tutorial, vamos apenas excluir todos os registros da Order Details tabela. Em um aplicativo do mundo real, precisamos de:

  • Ter outra tela para gerenciar informações de detalhes do pedido
  • Aumente o DeleteProduct método para incluir a lógica para excluir os detalhes do pedido do produto especificado
  • Modificar a consulta SQL usada pelo TableAdapter para incluir a exclusão dos detalhes do pedido do produto especificado

Vamos apenas excluir todos os registros da Order Details tabela para contornar a restrição de chave estrangeira. Vá para a Explorer do Servidor no Visual Studio, clique com o botão direito do mouse no NORTHWND.MDF nó e escolha Nova Consulta. Em seguida, na janela de consulta, execute a seguinte instrução SQL: DELETE FROM [Order Details]

Excluir todos os registros da tabela detalhes do pedido

Figura 14: Excluir todos os registros da Order Details tabela (clique para exibir a imagem em tamanho real)

Depois de limpar a Order Details tabela clicando no botão Excluir, excluirá o produto sem erros. Se clicar no botão Excluir não excluir o produto, marcar para garantir que a propriedade gridView DataKeyNames esteja definida como o campo de chave primária (ProductID).

Observação

Ao clicar no botão Excluir, um postback ocorre e o registro é excluído. Isso pode ser perigoso, pois é fácil clicar acidentalmente no botão Excluir 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

Juntamente com a exclusão, o controle GridView também fornece suporte interno à edição em nível de linha. Configurar um GridView para dar suporte à edição adiciona uma coluna de botões Editar. Na perspectiva 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 que contêm 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 o botão Cancelar para descartá-las. Em ambos os casos, depois de clicar em Atualizar ou Cancelar, o GridView retorna ao estado de pré-edição.

Da nossa perspectiva como desenvolvedor de páginas, quando o usuário final clica no botão Editar para uma linha específica, um postback se segue e o GridView executa as seguintes etapas:

  1. A propriedade GridView EditItemIndex é atribuída ao índice da linha cujo botão Editar foi clicado
  2. O GridView se vincula novamente ao ObjectDataSource invocando seu Select() método
  3. O índice de linha que corresponde ao EditItemIndex é renderizado no "modo de edição". Nesse modo, o botão Editar é substituído pelos botões Atualizar e Cancelar e BoundFields cujas ReadOnly propriedades são False (o padrão) são renderizadas como controles Web TextBox cujas Text propriedades sã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 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:

  1. Os valores do UpdateParameters ObjectDataSource são atribuídos aos valores inseridos pelo usuário final na interface de edição do GridView
  2. O método objectDataSource Update() é invocado, atualizando o registro especificado
  3. O GridView se vincula novamente ao ObjectDataSource invocando seu Select() método

Os valores de chave primária atribuídos ao 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 propriedade de DataKeyNames um GridView seja definida corretamente. Se ele estiver ausente, o valor da UpdateParameters chave primária será atribuído a um valor de Nothing na Etapa 1, o que, por sua vez, não resultará em nenhum registro atualizado na Etapa 2.

A funcionalidade de edição pode ser ativada simplesmente verificando a caixa de seleção Habilitar Edição na marca inteligente gridView.

Marque a caixa de seleção Habilitar Edição

Figura 15: Marque a caixa de seleção Habilitar Edição

A verificação da caixa de seleção Habilitar 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 quais séries de botões são exibidos no CommandField. A caixa de seleção Habilitar Edição adiciona a ShowEditButton propriedade 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>

Isso é tudo o que há para adicionar suporte de edição rudimentar. Como a Figura16 mostra, a interface de edição é bastante bruta cada BoundField cuja ReadOnly propriedade está definida False como (o padrão) é renderizada como uma TextBox. Isso inclui campos como CategoryID e SupplierID, que são chaves para outras tabelas.

Clicar no botão Editar do Chai s exibe a linha no modo de edição

Figura 16: Clicar no botão Editar Chai exibe a linha no modo de edição (clique para exibir a imagem em tamanho real)

Além de solicitar que os usuários editem valores de chave estrangeira diretamente, a interface da interface de edição não tem as seguintes maneiras:

  • Se o usuário inserir um CategoryID ou SupplierID que não existe no banco de dados, o UPDATE violará uma restrição de chave estrangeira, fazendo com que uma exceção seja gerada.
  • A interface de edição não inclui nenhuma validação. Se você não fornecer um valor necessário (como ProductName), ou inserir um valor de cadeia de caracteres em que um valor numérico é esperado (como inserir "Demais!" na UnitPrice caixa de texto), uma exceção será gerada. Um tutorial futuro examinará como adicionar controles de validação à interface do usuário de edição.
  • Atualmente, todos os campos de produto que não são somente leitura devem ser incluídos no GridView. Se removermos um campo do GridView, digamos UnitPrice, ao atualizar os dados, o GridView não definiria o UnitPriceUpdateParameters valor, o que alteraria o registro do banco de UnitPrice dados para um NULL valor. Da mesma forma, se um campo obrigatório, como ProductName, for removido do GridView, a atualização falhará com a mesma exceção "ProductName" de coluna não permite nulos" mencionada acima.
  • A formatação da interface de edição deixa muito a desejar. O UnitPrice é mostrado com quatro pontos decimais. O ideal é que os CategoryID valores e SupplierID contenham DropDownLists que listam as categorias e fornecedores no sistema.

Essas são todas as deficiências com as quais teremos que conviver por enquanto, mas 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 por 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 a 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 interno à inserção.

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 DetailsView. Em seguida, limpe as propriedades e Width do Height DetailsView e marcar a opção Habilitar Paginação da marca inteligente. Para habilitar a edição, inserção e exclusão de suporte, basta marcar as caixas de seleção Habilitar Edição, Habilitar Inserção e Habilitar Exclusão na marca inteligente.

Captura de tela mostrando a janela Tarefas DetailsView com as caixas de seleção Habilitar Inserção, Habilitar Edição e Habilitar Exclusão selecionadas.

Figura 17: Configurar o DetailsView para dar suporte à edição, à inserção e à exclusão

Assim como acontece com o GridView, adicionar edição, inserção ou exclusão de suporte 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.

Captura de tela do DetailsView com o CommandField aparecendo como uma linha inferior com os botões Inserir, Editar e Excluir.

Figura 18: Configurar o DetailsView para dar suporte à edição, à inserção e à exclusão (clique para exibir a imagem em tamanho real)

Clicar no botão Excluir inicia a mesma sequência de eventos que com GridView: um postback; seguido pelo DetailsView preenchendo seu ObjectDataSource com DeleteParameters base nos DataKeyNames valores e concluído com uma chamada do método objectDataSource Delete() , que realmente remove o produto do banco de dados. A edição no DetailsView também funciona de maneira idêntica à do GridView.

Para inserção, o usuário final recebe um botão Novo que, quando clicado, renderiza o DetailsView no "modo de inserção". Com o "modo de inserção", o botão Novo é substituído pelos botões Inserir e Cancelar e somente os BoundFields cuja InsertVisible propriedade está definida True como (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 False como ao associar o DetailsView à fonte de dados por meio da marca inteligente.

Ao associar uma fonte de dados a um DetailsView por meio da marca inteligente, o Visual Studio define a InsertVisible propriedade False como apenas para campos de incremento automático. 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 seja definida explicitamente como False. Reserve um momento para definir as propriedades desses dois campos InsertVisible como False, por meio da sintaxe declarativa do DetailsView ou por meio do link Editar Campos na marca inteligente. A Figura 19 mostra como definir as InsertVisible propriedades False clicando no link Editar Campos.

Captura de tela mostrando a janela Campos com a propriedade InsertVisible definida como False.

Figura 19: Northwind Traders agora oferece chá acme (clique para exibir imagem em tamanho real)

Depois de definir as InsertVisible propriedades, exiba a Basics.aspx página em um navegador e clique no botão Novo. A Figura 20 mostra o DetailsView ao adicionar uma nova bebida, Acme Tea, à nossa linha de produtos.

Captura de tela mostrando o DetailsView da página Basics.aspx em um navegador da Web.

Figura 20: Northwind Traders agora oferece acme tea (clique para exibir imagem em tamanho real)

Depois de inserir os detalhes do Acme Tea e clicar no botão Inserir, um postback se segue e o novo registro é adicionado à tabela de Products banco de dados. Como este DetailsView lista os produtos em ordem com os quais eles existem na tabela de banco de dados, devemos paginar para o último produto para ver o novo produto.

Detalhes do Acme Tea

Figura 21: Detalhes do Acme Tea (clique para exibir a imagem em tamanho real)

Observação

A propriedade CurrentMode do DetailsView indica a interface que está sendo exibida e pode ser um dos seguintes valores: Edit, Insertou ReadOnly. A propriedade DefaultMode indica o modo ao qual o DetailsView retorna após a conclusão de uma edição ou inserção e é útil para exibir um DetailsView permanentemente no modo de edição ou inserção.

Os recursos de inserção e edição de ponto e clique do DetailsView sofrem das mesmas limitações que o GridView: o usuário deve inserir valores existentes CategoryID e SupplierID por meio de uma caixa de texto; a interface não tem nenhuma lógica de validação; todos os campos de produto que não permitem NULL valores ou não têm um valor padrão especificado no nível do banco de dados devem ser incluídos na interface de inserção, e assim por diante.

As técnicas que examinaremos para estender e aprimorar 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 do 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 BoundFields ou CommandField usado pelos controles GridView e DetailsView para fornecer a interface de modificação de dados. Em vez disso, essa interface controla a Web para coletar a entrada do usuário ao adicionar um novo item ou editar um existente junto com os botões Novo, Editar, Excluir, Inserir, Atualizar e Cancelar devem ser adicionados manualmente aos modelos apropriados. Felizmente, o Visual Studio criará automaticamente a interface necessária ao associar o FormView a uma fonte de dados por meio da lista suspensa em sua marca inteligente.

Para ilustrar essas técnicas, comece adicionando um FormView à Basics.aspx página e, a partir da marca inteligente do FormView, associe-o ao ObjectDataSource já criado. Isso gerará um EditItemTemplate, InsertItemTemplatee ItemTemplate para o FormView com controles da Web TextBox para coletar a entrada do usuário e os controles da Web de botão para os botões Novo, Editar, Excluir, Inserir, Atualizar e Cancelar. Além disso, a propriedade do DataKeyNames FormView é definida como o campo de chave primária (ProductID) do objeto retornado pelo ObjectDataSource. Por fim, marcar a opção Habilitar Paginação na marca inteligente do FormView.

O exemplo a seguir mostra a marcação declarativa do ItemTemplate FormView após o FormView ter sido associado ao ObjectDataSource. Por padrão, cada campo de produto de valor não booliano é associado à Text propriedade de um controle Web Label, enquanto cada campo de valor booliano (Discontinued) está associado à Checked propriedade de um controle Web CheckBox desabilitado. Para que os botões Novo, Editar e Excluir disparem determinados comportamentos 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 formView ItemTemplate quando exibido por meio de um navegador. Cada campo de produto é listado com os botões Novo, Editar e Excluir na parte inferior.

O item Defaut FormViewTemplate Listas cada campo de produto junto com botões Novos, Editar e Excluir

Figura 22: O FormView ItemTemplate defasado Listas cada campo de produto junto com botões Novo, Editar e Excluir (clique para exibir a imagem em tamanho real)

Assim como acontece com GridView e DetailsView, clicar no botão Excluir ou em qualquer Button, LinkButton ou ImageButton cuja CommandName propriedade está definida como Delete causa um postback, preenche o objectDataSource DeleteParameters com base no valor do DataKeyNames FormView e invoca o método objectDataSource Delete() .

Quando o botão Editar é clicado, um postback é exibido e os dados são recuperados para o EditItemTemplate, que é responsável por renderizar a interface de edição. Essa interface inclui os controles da Web para editar dados junto com os botões Atualizar e Cancelar. O padrão EditItemTemplate gerado pelo Visual Studio contém um Rótulo para qualquer campo de incremento automático (ProductID), uma TextBox para cada campo de valor não booliano e uma CheckBox para cada campo de valor booliano. Esse 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 renderiza controles Da Web TextBox para os campos que são somente leitura, como CategoryName e SupplierName. Veremos como considerar isso em breve.

Os controles TextBox no EditItemTemplate têm sua Text propriedade associada ao valor do campo de dados correspondente usando a vinculação de dados bidirecional. A associação de dados bidirecional, indicada por <%# Bind("dataField") %>, executa a vinculação de dados ao associar 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 fizer suas alterações e clicar em Atualizar, os valores postados novamente que correspondem aos campos de dados especificados usando Bind() serão aplicados ao do UpdateParametersObjectDataSource. Como alternativa, a vinculação de dados unidirecional, indicada por , recupera apenas os valores de campo de dados ao associar dados ao modelo e não retorna os valores inseridos pelo <%# Eval("dataField") %>usuário aos parâmetros da fonte de dados no postback.

A marcação declarativa a seguir mostra o do EditItemTemplateFormView. Observe que o Bind() método é usado na sintaxe de associação de dados aqui e que os controles Web Atualizar e Cancelar Botão têm suas CommandName propriedades definidas adequadamente.

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

Nosso EditItemTemplate, neste ponto, fará com que uma exceção seja gerada se tentarmos usá-la. O problema é que os CategoryName campos e SupplierName são renderizados como controles Da Web TextBox no EditItemTemplate. Ou precisamos alterar essas TextBoxes para Rótulos ou removê-las completamente. Vamos simplesmente excluí-los inteiramente do EditItemTemplate.

A Figura 23 mostra o FormView em um navegador depois que o botão Editar foi clicado para Chai. Observe que os SupplierName campos e CategoryName mostrados no ItemTemplate não estão mais presentes, pois apenas os removemos do EditItemTemplate. Quando o botão Atualizar é clicado, o FormView prossegue pela mesma sequência de etapas que os controles GridView e DetailsView.

Por padrão, EditItemTemplate mostra cada campo de produto editável como uma Caixa de Texto ou Caixa de Seleção

Figura 23: por padrão, mostra cada EditItemTemplate campo de produto editável como uma Caixa de Texto ou Caixa de Seleção (clique para exibir a imagem em tamanho real)

Quando o botão Inserir é clicado, o postback do ItemTemplate FormView é exibido. No entanto, nenhum dado está associado 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 uma TextBox para cada campo de valor não booliano e uma CheckBox para cada campo de valor booliano, semelhante à interface gerada automaticamente EditItemTemplate. Os controles TextBox têm sua Text propriedade associada ao valor do campo de dados correspondente usando a vinculação de dados bidirecional.

A marcação declarativa a seguir mostra o do InsertItemTemplateFormView. Observe que o Bind() método é usado na sintaxe de associação de dados aqui e que os controles Web Inserir e Cancelar Botão têm suas CommandName propriedades 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>

Há uma sutileza com a geração automática do FormView do InsertItemTemplate. Especificamente, os controles da Web TextBox são criados até mesmo para os campos que são somente leitura, como CategoryName e SupplierName. Assim como com o EditItemTemplate, precisamos remover essas TextBoxes do InsertItemTemplate.

A Figura 24 mostra o FormView em um navegador ao adicionar um novo produto, Acme Coffee. Observe que os SupplierName campos e CategoryName mostrados no ItemTemplate não estão mais presentes, pois os removemos. 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 depois que ele foi inserido.

O InsertItemTemplate dita a interface de inserção do FormView

Figura 24: o InsertItemTemplate dita a interface de inserção do FormView (clique para exibir a imagem em tamanho real)

Os detalhes do novo produto, Acme Coffee, são exibidos no FormView

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

Assim 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 gravar 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 ponto e clique renderizam uma interface do usuário de modificação de dados bastante frágil e ingênua. Para fornecer validação, injetar valores programáticos, lidar normalmente com exceções, personalizar a interface do usuário e assim por diante, precisaremos contar com uma série de técnicas que serão discutidas nos próximos vários tutoriais.

Programação feliz!

Sobre o autor

Scott Mitchell, autor de sete livros do ASP/ASP.NET e fundador da 4GuysFromRolla.com, trabalha com tecnologias da Microsoft Web desde 1998. Scott trabalha como consultor independente, treinador e escritor. Seu último livro é Sams Teach Yourself ASP.NET 2.0 em 24 Horas. Ele pode ser contatado em mitchell@4GuysFromRolla.com. ou através de seu blog, que pode ser encontrado em http://ScottOnWriting.NET.