Uma visão geral da inserção, atualização e exclusão de dados (C#)
por Scott Mitchell
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).
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
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.
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.
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.
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.
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 , AddProduct
e DeleteProduct
da UpdateProduct
classe, respectivamente.
Figura 7: Mapear o método ObjectDataSource Update()
para o ProductBLL
método da UpdateProduct
classe (clique para exibir a imagem em tamanho real)
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)
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 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ê 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
, UpdateParameters
e InsertParameters
que mapeiam para os parâmetros de entrada para os ProductsBLL
métodos , UpdateProduct
e DeleteProduct
da AddProduct
classe:
<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
, UpdateParameters
e 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
ProductID
campos ,CategoryName
eSupplierName
são marcados como somente leitura noProductsDataTable
e, portanto, não devem ser atualizáveis ao editar. Para acomodar isso, as propriedades ReadOnly desses BoundFields são definidastrue
como . - 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. Para obter mais informações sobre a
DataKeyNames
propriedade , consulte o tutorial Mestre/Detalhe usando um Selectable Master GridView com um 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 de uma linha específica, um postback é seguido e o GridView executa as seguintes etapas:
- Os valores de
DeleteParameters
ObjectDataSource são atribuídos - O método objectDataSource
Delete()
é invocado, excluindo o registro especificado - O GridView se associa novamente ao ObjectDataSource invocando seu
Select()
método
Os valores atribuídos a são DeleteParameters
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 null
valor 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 como EnableViewState
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 acidentalmente excluir ou editar registros 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.
Figura 10: Marque a caixa de seleção Habilitar Exclusão
Marcar 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 tutorial Mestre/Detalhes usando um Selectable Master GridView com detalhesExibição detalhada.
O CommandField contém várias ShowXButton
propriedades que indicam quais séries de botões são exibidos no CommandField. Marcando a caixa de seleção Habilitar Exclusão, um CommandField cuja ShowDeleteButton
propriedade é true
foi 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.
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, clicar 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ê 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 OldValuesParameterFormatString
propriedade especificada, o ObjectDataSource tenta passar os productID
parâmetros 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 {0}
como ) instrui o ObjectDataSource a não tentar passar o parâmetro de entrada original.
Figura 12: Verifique se a OldValuesParameterFormatString
propriedade foi desmarcada (clique para exibir a 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 está 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 tabela e Products
, o Order Details
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 do pedido associado do produto.
Figura 13: Uma restrição de chave estrangeira proíbe a exclusão de produtos (clique para exibir a imagem em tamanho real)
Para 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 informações de detalhes do pedido
- Aumentar 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 servidor no Visual Studio, clique com o botão direito do NORTHWND.MDF
mouse no nó 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 Order Details
tabela (clique para exibir a imagem em tamanho real)
Depois de limpar a Order Details
tabela clicando no botão Excluir, o produto será excluído 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 é gerado 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. Da 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 retornará ao seu estado de pré-edição.
Da nossa perspectiva como desenvolvedor de página, quando o usuário final clica no botão Editar para uma linha específica, um postback é seguido e o GridView executa as seguintes etapas:
- A propriedade gridView
EditItemIndex
é atribuída ao índice da linha cujo botão Editar foi clicado - O GridView se associa novamente ao ObjectDataSource invocando seu
Select()
método - 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 cujasReadOnly
propriedades são False (o padrão) são renderizados como controles Da Web TextBox cujasText
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:
- Os valores de
UpdateParameters
ObjectDataSource são atribuídos aos valores inseridos pelo usuário final na interface de edição do GridView - O método objectDataSource
Update()
é invocado, atualizando o registro especificado - O GridView se associa 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 receberá um null
valor 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 marcando a caixa de seleção Habilitar Edição na marca inteligente gridView.
Figura 15: Marque a caixa de seleção Habilitar Edição
Marcar a caixa de seleção Habilitar Edição adicionará um CommandField (se necessário) e definirá sua ShowEditButton
propriedade como true
. Como vimos anteriormente, CommandField contém várias ShowXButton
propriedades que indicam quais séries de botões são exibidos no CommandField. Marcar 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 mostra a Figura16, a interface de edição é bastante bruta cada BoundField cuja ReadOnly
propriedade está definida false
como (o padrão) é renderizada como textbox. Isso inclui campos como CategoryID
e SupplierID
, que são chaves para outras tabelas.
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
ouSupplierID
que não existe no banco de dados, oUPDATE
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!" naUnitPrice
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 oUnitPrice
UpdateParameters
valor, o que alteraria o registro do banco deUnitPrice
dados para umNULL
valor. Da mesma forma, se um campo obrigatório, comoProductName
, 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 osCategoryID
valores eSupplierID
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.
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.
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.
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.
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.
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
, Insert
ou 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
, InsertItemTemplate
e 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
, Edit
e 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.
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 UpdateParameters
ObjectDataSource. 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 EditItemTemplate
FormView. 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.
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 InsertItemTemplate
FormView. 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.
Figura 24: o InsertItemTemplate
dita a interface de inserção do FormView (clique para exibir 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
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.
Comentários
https://aka.ms/ContentUserFeedback.
Brevemente: Ao longo de 2024, vamos descontinuar progressivamente o GitHub Issues como mecanismo de feedback para conteúdos e substituí-lo por um novo sistema de feedback. Para obter mais informações, veja:Submeter e ver comentários