Examinar os eventos associados à inserção, atualização e exclusão (VB)
por Scott Mitchell
Neste tutorial, examinaremos o uso dos eventos que ocorrem antes, durante e depois de uma operação de inserção, atualização ou exclusão de um controle Web de dados ASP.NET. Também veremos como personalizar a interface de edição para atualizar apenas um subconjunto dos campos do produto.
Introdução
Ao usar os recursos internos de inserção, edição ou exclusão dos controles GridView, DetailsView ou FormView, várias etapas ocorrem quando o usuário final conclui o processo de adição de um novo registro ou atualização ou exclusão de um registro existente. Como discutimos no tutorial anterior, quando uma linha é editada no GridView, o botão Editar é substituído pelos botões Atualizar e Cancelar e os BoundFields se transformam em TextBoxes. Depois que o usuário final atualiza os dados e clica em Atualizar, as seguintes etapas são executadas no postback:
- O GridView preenche seus ObjectDataSources
UpdateParameters
com os campos de identificação exclusivos do registro editado (por meio daDataKeyNames
propriedade) junto com os valores inseridos pelo usuário - O GridView invoca o método de
Update()
ObjectDataSource, que, por sua vez, invoca o método apropriado no objeto subjacente (ProductsDAL.UpdateProduct
, em nosso tutorial anterior) - Os dados subjacentes, que agora incluem as alterações atualizadas, são reabilitados para o GridView
Durante essa sequência de etapas, vários eventos são acionados, permitindo-nos criar manipuladores de eventos para adicionar lógica personalizada quando necessário. Por exemplo, antes da Etapa 1, o evento do RowUpdating
GridView é acionado. Podemos, neste momento, cancelar a solicitação de atualização se houver algum erro de validação. Quando o Update()
método é invocado, o evento do Updating
ObjectDataSource é acionado, fornecendo uma oportunidade de adicionar ou personalizar os valores de qualquer um dos UpdateParameters
arquivos . Depois que o método do objeto subjacente do ObjectDataSource tiver concluído a execução, o evento do Updated
ObjectDataSource será gerado. Um manipulador de eventos para o Updated
evento pode inspecionar os detalhes sobre a operação de atualização, como quantas linhas foram afetadas e se ocorreu ou não uma exceção. Por fim, após a Etapa 2, o evento do GridView é acionado; um manipulador de RowUpdated
eventos para esse evento pode examinar informações adicionais sobre a operação de atualização que acabou de ser executada.
A Figura 1 ilustra essa série de eventos e etapas ao atualizar um GridView. O padrão de evento na Figura 1 não é exclusivo para atualizar com um GridView. Inserir, atualizar ou excluir dados do GridView, DetailsView ou FormView precipita a mesma sequência de eventos de pré e pós-nível para o controle Web de dados e o ObjectDataSource.
Figura 1: Uma série de disparos pré e pós-eventos ao atualizar dados em um GridView (clique para exibir a imagem em tamanho real)
Neste tutorial, examinaremos o uso desses eventos para estender os recursos internos de inserção, atualização e exclusão dos controles Web de dados ASP.NET. Também veremos como personalizar a interface de edição para atualizar apenas um subconjunto dos campos do produto.
Etapa 1: Atualizando os campos eProductName
UnitPrice
os produtos
Nas interfaces de edição do tutorial anterior, todos os campos do produto que não eram somente leitura tiveram que ser incluídos. Se fôssemos remover um campo do GridView - digamos QuantityPerUnit
- ao atualizar os dados, o controle Web de dados não definiria o valor do QuantityPerUnit
UpdateParameters
ObjectDataSource. Em seguida, o ObjectDataSource passaria um valor de para o UpdateProduct
método BLL (Business Logic Layer), que alteraria a coluna do QuantityPerUnit
registro de Nothing
banco de dados editado para um NULL
valor. Da mesma forma, se um campo obrigatório, como ProductName
, for removido da interface de edição, a atualização falhará com uma exceção "A coluna 'ProductName' não permite nulos". O motivo desse comportamento foi porque o ObjectDataSource foi configurado para chamar o ProductsBLL
método da UpdateProduct
classe, que esperava um parâmetro de entrada para cada um dos campos do produto. Portanto, a coleção do UpdateParameters
ObjectDataSource continha um parâmetro para cada um dos parâmetros de entrada do método.
Se quisermos fornecer um controle Web de dados que permita que o usuário final atualize apenas um subconjunto de campos, precisaremos definir programaticamente os valores ausentes UpdateParameters
no manipulador de Updating
eventos do ObjectDataSource ou criar e chamar um método BLL que espera apenas um subconjunto dos campos. Vamos explorar esta última abordagem.
Especificamente, vamos criar uma página que exiba apenas os ProductName
campos e UnitPrice
em um GridView editável. A interface de edição deste GridView só permitirá que o usuário atualize os dois campos ProductName
exibidos e UnitPrice
. Como essa interface de edição fornece apenas um subconjunto dos campos de um produto, precisamos criar um ObjectDataSource que use o método da BLL existente e tenha os valores de campo de produto ausentes UpdateProduct
definidos programaticamente em seu Updating
manipulador de eventos ou precisamos criar um novo método BLL que espere apenas o subconjunto de campos definidos no GridView. Para este tutorial, vamos usar a última opção e criar uma sobrecarga do método, que recebe apenas três parâmetros de UpdateProduct
entrada: productName
, unitPrice
, e productID
:
<System.ComponentModel.DataObjectMethodAttribute _
(System.ComponentModel.DataObjectMethodType.Update, False)> _
Public Function UpdateProduct(productName As String, _
unitPrice As Nullable(Of Decimal), productID As Integer) _
As Boolean
Dim products As Northwind.ProductsDataTable = _
Adapter.GetProductByProductID(productID)
If products.Count = 0 Then
Return False
End If
Dim product As Northwind.ProductsRow = products(0)
product.ProductName = productName
If Not unitPrice.HasValue Then
product.SetUnitPriceNull()
Else
product.UnitPrice = unitPrice.Value
End If
Dim rowsAffected As Integer = Adapter.Update(product)
Return rowsAffected = 1
End Function
Como o método original UpdateProduct
, essa sobrecarga começa verificando se há um produto no banco de dados com o ProductID
. Caso contrário, ele retornará False
, indicando que a solicitação para atualizar as informações do produto falhou. Caso contrário, ele atualiza o registro de ProductName
produto existente e UnitPrice
os campos de acordo e confirma a atualização chamando o método do Update()
TableAdapter, passando a ProductsRow
instância.
Com essa adição à nossa ProductsBLL
classe, estamos prontos para criar a interface simplificada do GridView. Abra o DataModificationEvents.aspx
EditInsertDelete
na pasta e adicione um GridView à página. Crie um novo ObjectDataSource e configure-o para usar a ProductsBLL
classe com seu Select()
mapeamento de método para GetProducts
e seu Update()
mapeamento de método para a UpdateProduct
sobrecarga que usa apenas os productName
parâmetros , unitPrice
, e productID
input. A Figura 2 mostra o assistente Criar Fonte de Dados ao mapear o método do Update()
ObjectDataSource para a ProductsBLL
nova UpdateProduct
sobrecarga de método da classe.
Figura 2: Mapear o método do Update()
ObjectDataSource para a nova UpdateProduct
sobrecarga (clique para exibir a imagem em tamanho completo)
Como nosso exemplo inicialmente precisará apenas da capacidade de editar dados, mas não de inserir ou excluir registros, reserve um momento para indicar explicitamente que os ObjectDataSource's Insert()
e Delete()
os métodos não devem ser mapeados para nenhum dos ProductsBLL
métodos da classe acessando as guias INSERT e DELETE e escolhendo (Nenhum) na lista suspensa.
Figura 3: Escolha (Nenhum) na lista suspensa para as guias INSERT e DELETE (clique para exibir a imagem em tamanho real)
Depois de concluir este assistente, marque a caixa de seleção Habilitar edição na marca inteligente do GridView.
Com a conclusão do assistente Criar Fonte de Dados e associando-o ao GridView, o Visual Studio criou a sintaxe declarativa para ambos os controles. Vá para o modo de exibição Source para inspecionar a marcação declarativa do ObjectDataSource, que é mostrada abaixo:
<asp:ObjectDataSource ID="ObjectDataSource1" runat="server"
OldValuesParameterFormatString="original_{0}" SelectMethod="GetProducts"
TypeName="ProductsBLL" UpdateMethod="UpdateProduct">
<UpdateParameters>
<asp:Parameter Name="productName" Type="String" />
<asp:Parameter Name="unitPrice" Type="Decimal" />
<asp:Parameter Name="productID" Type="Int32" />
</UpdateParameters>
</asp:ObjectDataSource>
Como não há mapeamentos para os ObjectDataSource's Insert()
e Delete()
métodos, não há seções InsertParameters
or DeleteParameters
. Além disso, como o Update()
método é mapeado para a sobrecarga do UpdateProduct
método que aceita apenas três parâmetros de entrada, a UpdateParameters
seção tem apenas três Parameter
instâncias.
Observe que a propriedade do ObjectDataSource OldValuesParameterFormatString
é definida como original_{0}
. Essa propriedade é definida automaticamente pelo Visual Studio ao usar o assistente Configurar Fonte de Dados. No entanto, como nossos métodos BLL não esperam que o valor original ProductID
seja passado, remova essa atribuição de propriedade completamente da sintaxe declarativa do ObjectDataSource.
Observação
Se você simplesmente limpar o OldValuesParameterFormatString
valor da propriedade da janela Propriedades na visualização Design, a propriedade ainda existirá na sintaxe declarativa, mas será definida como uma cadeia de caracteres vazia. Remova a propriedade completamente da sintaxe declarativa ou, na janela Propriedades, defina o valor como o padrão, {0}
.
Embora o ObjectDataSource tenha UpdateParameters
apenas o nome, o preço e a ID do produto, o Visual Studio adicionou um BoundField ou CheckBoxField no GridView para cada um dos campos do produto.
Figura 4: O GridView contém um BoundField ou CheckBoxField para cada um dos campos do produto (clique para exibir a imagem em tamanho real)
Quando o usuário final edita um produto e clica no botão Atualizar, o GridView enumera os campos que não eram somente leitura. Em seguida, ele define o valor do parâmetro correspondente na coleção do ObjectDataSource UpdateParameters
como o valor inserido pelo usuário. Se não houver um parâmetro correspondente, o GridView adicionará um à coleção. Portanto, se nosso GridView contiver BoundFields e CheckBoxFields para todos os campos do produto, o ObjectDataSource acabará invocando a UpdateProduct
sobrecarga que absorve todos esses parâmetros, apesar do fato de que a marcação declarativa do ObjectDataSource especifica apenas três parâmetros de entrada (consulte a Figura 5). Da mesma forma, se houver alguma combinação de campos de produto não somente leitura no GridView que não corresponda aos parâmetros de entrada para uma UpdateProduct
sobrecarga, uma exceção será gerada ao tentar atualizar.
Figura 5: O GridView adicionará parâmetros à coleção do UpdateParameters
ObjectDataSource (clique para exibir a imagem em tamanho completo)
Para garantir que o ObjectDataSource invoque a UpdateProduct
sobrecarga que inclui apenas o nome, o preço e a ID do produto, precisamos restringir o GridView a ter campos editáveis apenas para o ProductName
e UnitPrice
. Isso pode ser feito removendo os outros BoundFields e CheckBoxFields, definindo a propriedade desses ReadOnly
outros campos como True
, ou por alguma combinação dos dois. Para este tutorial, vamos simplesmente remover todos os campos GridView, exceto o e UnitPrice
BoundFieldsProductName
, após o qual a marcação declarativa do GridView será semelhante a:
<asp:GridView ID="GridView1" runat="server" AutoGenerateColumns="False"
DataKeyNames="ProductID" DataSourceID="ObjectDataSource1">
<Columns>
<asp:CommandField ShowEditButton="True" />
<asp:BoundField DataField="ProductName"
HeaderText="ProductName" SortExpression="ProductName" />
<asp:BoundField DataField="UnitPrice" HeaderText="UnitPrice"
SortExpression="UnitPrice" />
</Columns>
</asp:GridView>
Embora a UpdateProduct
sobrecarga espere três parâmetros de entrada, temos apenas dois BoundFields em nosso GridView. Isso ocorre porque o productID
parâmetro de entrada é um valor de chave primária e passado por meio do valor da DataKeyNames
propriedade para a linha editada.
Nosso GridView, juntamente com a UpdateProduct
sobrecarga, permite que um usuário edite apenas o nome e o preço de um produto sem perder nenhum dos outros campos do produto.
Figura 6: A interface permite editar apenas o nome e o preço do produto (clique para exibir a imagem em tamanho real)
Observação
Conforme discutido no tutorial anterior, é de vital importância que o estado de exibição do GridView seja habilitado (o comportamento padrão). Se você definir a propriedade do GridView como false
, correrá o risco de ter usuários simultâneos EnableViewState
excluindo ou editando registros acidentalmente.
Melhorando aUnitPrice
formatação
Embora o exemplo do GridView mostrado na Figura 6 funcione, o UnitPrice
campo não está formatado, resultando em uma exibição de preço que não possui nenhum símbolo de moeda e tem quatro casas decimais. Para aplicar uma formatação de moeda para as linhas não editáveis, basta definir a propriedade do DataFormatString
BoundField como {0:c}
e sua HtmlEncode
propriedade como False
.UnitPrice
Figura 7: Defina as propriedades de 's DataFormatString
e HtmlEncode
de acordo (clique para exibir a UnitPrice
imagem em tamanho real)
Com essa alteração, as linhas não editáveis formatam o preço como uma moeda; A linha editada, no entanto, ainda exibe o valor sem o símbolo de moeda e com quatro casas decimais.
Figura 8: As linhas não editáveis agora estão formatadas como valores de moeda (clique para exibir a imagem em tamanho real)
As instruções de formatação especificadas na DataFormatString
propriedade podem ser aplicadas à interface de edição definindo a propriedade do BoundField como True
(o padrão é False
).ApplyFormatInEditMode
Reserve um momento para definir essa propriedade como True
.
Figura 9: Defina a UnitPrice
propriedade do ApplyFormatInEditMode
BoundField como True
(clique para exibir a imagem em tamanho real)
Com essa alteração, o UnitPrice
valor do exibido na linha editada também é formatado como uma moeda.
Figura 10: O valor da linha editada UnitPrice
agora está formatado como uma moeda (clique para exibir a imagem em tamanho real)
No entanto, atualizar um produto com o símbolo de moeda na caixa de texto, como US$ 19,00, gera um FormatException
. Quando o GridView tenta atribuir os valores fornecidos pelo usuário à coleção do UpdateParameters
ObjectDataSource, ele não consegue converter a UnitPrice
cadeia de caracteres "$19.00" na Decimal
exigida pelo parâmetro (consulte a Figura 11). Para remediar isso, podemos criar um manipulador de eventos para o evento do RowUpdating
GridView e fazer com que ele analise o fornecido pelo usuário UnitPrice
como um formato de Decimal
moeda .
O evento do RowUpdating
GridView aceita como seu segundo parâmetro um objeto do tipo GridViewUpdateEventArgs, que inclui um NewValues
dicionário como uma de suas propriedades que contém os valores fornecidos pelo usuário prontos para serem atribuídos à coleção do UpdateParameters
ObjectDataSource. Podemos substituir o NewValues
valor existente UnitPrice
na coleção por um valor decimal analisado usando o formato de moeda com as seguintes linhas de código no RowUpdating
manipulador de eventos:
Protected Sub GridView1_RowUpdating(sender As Object, e As GridViewUpdateEventArgs) _
Handles GridView1.RowUpdating
If e.NewValues("UnitPrice") IsNot Nothing Then
e.NewValues("UnitPrice") = _
Decimal.Parse(e.NewValues("UnitPrice").ToString(), _
System.Globalization.NumberStyles.Currency)
End If
End Sub
Se o usuário tiver fornecido um UnitPrice
valor (como "US$ 19,00"), esse valor será substituído pelo valor decimal calculado por Decimal.Parse, analisando o valor como uma moeda. Isso analisará corretamente o decimal no caso de símbolos de moeda, vírgulas, pontos decimais e assim por diante, e usará a enumeração NumberStyles no namespace System.Globalization .
A Figura 11 mostra o problema causado por símbolos de moeda no , fornecido UnitPrice
pelo usuário, juntamente com a forma como o manipulador de RowUpdating
eventos do GridView pode ser utilizado para analisar corretamente essa entrada.
Figura 11: O valor da linha editada UnitPrice
agora está formatado como uma moeda (clique para exibir a imagem em tamanho real)
Passo 2: ProibindoNULL UnitPrices
Embora o banco de dados esteja configurado para permitir NULL
valores na Products
coluna da UnitPrice
tabela, talvez queiramos impedir que os usuários que visitam essa página específica especifiquem um NULL
UnitPrice
valor. Ou seja, se um usuário não inserir um UnitPrice
valor ao editar uma linha de produto, em vez de salvar os resultados no banco de dados, queremos exibir uma mensagem informando ao usuário que, por meio dessa página, todos os produtos editados devem ter um preço especificado.
O GridViewUpdateEventArgs
objeto passado para o manipulador de eventos do RowUpdating
GridView contém uma Cancel
propriedade que, se definida como True
, encerra o processo de atualização. Vamos estender o RowUpdating
manipulador de eventos para definir e.Cancel
e True
exibir uma mensagem explicando por que, se o UnitPrice
valor na NewValues
coleção tiver um valor de Nothing
.
Comece adicionando um controle Web Label à página chamada MustProvideUnitPriceMessage
. Esse controle de rótulo será exibido se o usuário não especificar um UnitPrice
valor ao atualizar um produto. Defina a propriedade do Text
rótulo como "Você deve fornecer um preço para o produto". Também criei uma nova classe CSS nomeada Warning
com Styles.css
a seguinte definição:
.Warning
{
color: Red;
font-style: italic;
font-weight: bold;
font-size: x-large;
}
Por fim, defina a propriedade do CssClass
rótulo como Warning
. Neste ponto, o Designer deve mostrar a mensagem de aviso em um tamanho de fonte vermelho, negrito, itálico e extra grande acima do GridView, conforme mostrado na Figura 12.
Figura 12: Um rótulo foi adicionado acima do GridView (clique para exibir a imagem em tamanho real)
Por padrão, esse rótulo deve estar oculto, portanto, defina sua Visible
propriedade como False
no manipulador de Page_Load
eventos:
Protected Sub Page_Load(sender As Object, e As System.EventArgs) Handles Me.Load
MustProvideUnitPriceMessage.Visible = False
End Sub
Se o usuário tentar atualizar um produto sem especificar o UnitPrice
, desejaremos cancelar a atualização e exibir o rótulo de aviso. Aumente o manipulador de eventos do RowUpdating
GridView da seguinte maneira:
Protected Sub GridView1_RowUpdating(sender As Object, e As GridViewUpdateEventArgs) _
Handles GridView1.RowUpdating
If e.NewValues("UnitPrice") IsNot Nothing Then
e.NewValues("UnitPrice") = _
Decimal.Parse(e.NewValues("UnitPrice").ToString(), _
System.Globalization.NumberStyles.Currency)
Else
MustProvideUnitPriceMessage.Visible = True
e.Cancel = True
End If
End Sub
Se um usuário tentar salvar um produto sem especificar um preço, a atualização será cancelada e uma mensagem útil será exibida. Embora o banco de dados (e a lógica de negócios) permita NULL
UnitPrice
s, esta página ASP.NET específica não.
Figura 13: Um usuário não pode deixar UnitPrice
em branco (clique para exibir a imagem em tamanho real)
Até agora, vimos como usar o evento do GridView para alterar programaticamente os valores de RowUpdating
parâmetro atribuídos à coleção do UpdateParameters
ObjectDataSource, bem como cancelar completamente o processo de atualização. Esses conceitos são transferidos para os controles DetailsView e FormView e também se aplicam à inserção e exclusão.
Essas tarefas também podem ser feitas no nível ObjectDataSource por meio de manipuladores de eventos para seus Inserting
eventos , Updating
e Deleting
. Esses eventos são acionados antes que o método associado do objeto subjacente seja invocado e fornecem uma oportunidade de última chance de modificar a coleção de parâmetros de entrada ou cancelar a operação imediatamente. Os manipuladores de eventos para esses três eventos recebem um objeto do tipo ObjectDataSourceMethodEventArgs que tem duas propriedades de interesse:
- Cancelar, que, se definido como
True
, cancela a operação que está sendo executada - InputParameters, que é a coleção de ,
UpdateParameters
, ouDeleteParameters
, dependendo se o manipulador deInsertParameters
eventos é para oInserting
evento ,Updating
, ouDeleting
Para ilustrar o trabalho com os valores de parâmetro no nível ObjectDataSource, vamos incluir um DetailsView em nossa página que permite que os usuários adicionem um novo produto. Esse DetailsView será usado para fornecer uma interface para adicionar rapidamente um novo produto ao banco de dados. Para manter uma interface de usuário consistente ao adicionar um novo produto, vamos permitir que o usuário insira apenas valores para os ProductName
campos e UnitPrice
. Por padrão, os valores que não são fornecidos na interface de inserção do DetailsView serão definidos como um NULL
valor de banco de dados. No entanto, podemos usar o evento do Inserting
ObjectDataSource para injetar valores padrão diferentes, como veremos em breve.
Etapa 3: Fornecendo uma interface para adicionar novos produtos
Arraste um DetailsView da Caixa de Ferramentas para o Designer acima do GridView, limpe suas Height
propriedades e Width
associe-o ao ObjectDataSource já presente na página. Isso adicionará um BoundField ou CheckBoxField para cada um dos campos do produto. Como queremos usar esse DetailsView para adicionar novos produtos, precisamos marcar a opção Habilitar inserção na marca inteligente; no entanto, não há essa opção porque o método do Insert()
ObjectDataSource não é mapeado para um método na classe (lembre-se de que definimos esse mapeamento como (None) ao configurar a fonte de dados, consulte a ProductsBLL
Figura 3).
Para configurar o ObjectDataSource, selecione o link Configurar Fonte de Dados em sua marca inteligente, iniciando o assistente. A primeira tela permite que você altere o objeto subjacente ao qual o ObjectDataSource está vinculado; deixe-o definido como ProductsBLL
. A próxima tela lista os mapeamentos dos métodos do ObjectDataSource para os do objeto subjacente. Embora tenhamos indicado explicitamente que os Insert()
métodos e Delete()
não devem ser mapeados para nenhum método, se você for para as guias INSERT e DELETE, verá que um mapeamento está lá. Isso ocorre porque os ProductsBLL
métodos 's AddProduct
e DeleteProduct
usam o DataObjectMethodAttribute
atributo para indicar que são os métodos padrão para Insert()
e Delete()
, respectivamente. Portanto, o assistente ObjectDataSource os seleciona sempre que você executa o assistente, a menos que haja algum outro valor especificado explicitamente.
Deixe o Insert()
método apontando para o AddProduct
método, mas defina novamente a lista suspensa da guia DELETE como (Nenhum).
Figura 14: Definir a lista suspensa da guia INSERT como o método (clique para exibir a AddProduct
imagem em tamanho real)
Figura 15: Defina a lista suspensa da guia DELETE como (Nenhuma) (clique para exibir a imagem em tamanho real)
Depois de fazer essas alterações, a sintaxe declarativa do ObjectDataSource será expandida para incluir uma InsertParameters
coleção, conforme mostrado abaixo:
<asp:ObjectDataSource ID="ObjectDataSource1" runat="server"
SelectMethod="GetProducts" TypeName="ProductsBLL"
UpdateMethod="UpdateProduct" OnUpdating="ObjectDataSource1_Updating"
InsertMethod="AddProduct" OldValuesParameterFormatString="original_{0}">
<UpdateParameters>
<asp:Parameter Name="productName" Type="String" />
<asp:Parameter Name="unitPrice" Type="Decimal" />
<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>
Executar novamente o assistente adicionou de volta a OldValuesParameterFormatString
propriedade. Reserve um momento para limpar essa propriedade definindo-a como o valor padrão ({0}
) ou removendo-a completamente da sintaxe declarativa.
Com o ObjectDataSource fornecendo recursos de inserção, a marca inteligente do DetailsView agora incluirá a caixa de seleção Habilitar Inserção; retorne ao Designer e marque esta opção. Em seguida, reduza o DetailsView para que ele tenha apenas dois BoundFields - ProductName
e UnitPrice
- e o CommandField. Neste ponto, a sintaxe declarativa do DetailsView deve ser semelhante a:
<asp:DetailsView ID="DetailsView1" runat="server" AutoGenerateRows="False"
DataKeyNames="ProductID" DataSourceID="ObjectDataSource1">
<Fields>
<asp:BoundField DataField="ProductName"
HeaderText="ProductName" SortExpression="ProductName" />
<asp:BoundField DataField="UnitPrice" HeaderText="UnitPrice"
SortExpression="UnitPrice" />
<asp:CommandField ShowInsertButton="True" />
</Fields>
</asp:DetailsView>
A Figura 16 mostra esta página quando visualizada por meio de um navegador neste momento. Como você pode ver, o DetailsView lista o nome e o preço do primeiro produto (Chai). O que queremos, no entanto, é uma interface de inserção que forneça um meio para o usuário adicionar rapidamente um novo produto ao banco de dados.
Figura 16: O DetailsView está atualmente renderizado no modo somente leitura (clique para exibir a imagem em tamanho real)
Para mostrar o DetailsView em seu modo de inserção, precisamos definir a DefaultMode
propriedade como Inserting
. Isso renderiza o DetailsView no modo de inserção quando visitado pela primeira vez e o mantém lá após a inserção de um novo registro. Como mostra a Figura 17, esse DetailsView fornece uma interface rápida para adicionar um novo registro.
Figura 17: O DetailsView fornece uma interface para adicionar rapidamente um novo produto (clique para exibir a imagem em tamanho real)
Quando o usuário insere um nome e preço de produto (como "Acme Water" e 1.99, como na Figura 17) e clica em Inserir, ocorre um postback e o fluxo de trabalho de inserção é iniciado, culminando na inclusão de um novo registro de produto no banco de dados. O DetailsView mantém sua interface de inserção e o GridView é automaticamente reassociado à sua fonte de dados para incluir o novo produto, conforme mostrado na Figura 18.
Figura 18: O produto "Acme Water" foi adicionado ao banco de dados
Embora o GridView na Figura 18 não o mostre, os campos de produto ausentes da interface CategoryID
DetailsView , SupplierID
, QuantityPerUnit
e assim por diante recebem NULL
valores de banco de dados. Você pode ver isso executando as seguintes etapas:
- Vá para o Gerenciador de Servidores no Visual Studio
- Expandindo o nó do
NORTHWND.MDF
banco de dados - Clique com o botão direito do mouse no nó da
Products
tabela do banco de dados - Selecione Mostrar dados da tabela
Isso listará todos os registros na Products
tabela. Como mostra a Figura 19, todas as colunas do nosso novo produto, exceto ProductID
, ProductName
, e UnitPrice
têm NULL
valores.
Figura 19: Os campos de produto não fornecidos no DetailsView são valores atribuídos NULL
(clique para exibir a imagem em tamanho real)
Podemos querer fornecer um valor padrão diferente de NULL
um ou mais desses valores de coluna, seja porque NULL
não é a melhor opção padrão ou porque a própria coluna do banco de dados não permite NULL
s. Para fazer isso, podemos definir programaticamente os valores dos parâmetros da InputParameters
coleção do DetailsView. Essa atribuição pode ser feita no manipulador de ItemInserting
eventos para o evento do DetailsView ou do evento do ObjectDataSource Inserting
. Como já vimos o uso dos eventos de nível pré e pós no nível de controle Web de dados, vamos explorar o uso dos eventos do ObjectDataSource desta vez.
Etapa 4: Atribuindo valores aosCategoryID
parâmetros eSupplierID
Para este tutorial, vamos imaginar que, para nosso aplicativo, ao adicionar um novo produto por meio dessa interface, ele deve receber um CategoryID
valor e SupplierID
1. Como mencionado anteriormente, o ObjectDataSource tem um par de eventos de pré e pós-nível que são acionados durante o processo de modificação de dados. Quando seu Insert()
método é invocado, o ObjectDataSource primeiro gera seu Inserting
evento, depois chama o método para o qual seu Insert()
método foi mapeado e, finalmente, gera o Inserted
evento. O Inserting
manipulador de eventos nos oferece uma última oportunidade de ajustar os parâmetros de entrada ou cancelar a operação imediatamente.
Observação
Em um aplicativo do mundo real, você provavelmente gostaria de permitir que o usuário especifique a categoria e o fornecedor ou escolher esse valor para eles com base em alguns critérios ou lógica de negócios (em vez de selecionar cegamente uma ID de 1). Independentemente disso, o exemplo ilustra como definir programaticamente o valor de um parâmetro de entrada do evento de pré-nível do ObjectDataSource.
Reserve um momento para criar um manipulador de Inserting
eventos para o evento do ObjectDataSource. Observe que o segundo parâmetro de entrada do manipulador de eventos é um objeto do tipo ObjectDataSourceMethodEventArgs
, que tem uma propriedade para acessar a coleção de parâmetros (InputParameters
) e uma propriedade para cancelar a operação (Cancel
).
Protected Sub ObjectDataSource1_Inserting _
(sender As Object, e As ObjectDataSourceMethodEventArgs) _
Handles ObjectDataSource1.Inserting
End Sub
Neste ponto, a InputParameters
propriedade contém a coleção do InsertParameters
ObjectDataSource com os valores atribuídos do DetailsView. Para alterar o valor de um desses parâmetros, basta usar: e.InputParameters("paramName") = value
. Portanto, para definir os CategoryID
valores e SupplierID
para de 1, ajuste o Inserting
manipulador de eventos para se parecer com o seguinte:
Protected Sub ObjectDataSource1_Inserting _
(sender As Object, e As ObjectDataSourceMethodEventArgs) _
Handles ObjectDataSource1.Inserting
e.InputParameters("CategoryID") = 1
e.InputParameters("SupplierID") = 1
End Sub
Desta vez, ao adicionar um novo produto (como Acme Soda), as CategoryID
colunas e SupplierID
do novo produto são definidas como 1 (consulte a Figura 20).
Figura 20: Novos produtos agora têm seus CategoryID
valores e SupplierID
definidos como 1 (clique para exibir a imagem em tamanho real)
Resumo
Durante o processo de edição, inserção e exclusão, o controle Web de dados e o ObjectDataSource passam por vários eventos de pré e pós-nível. Neste tutorial, examinamos os eventos de pré-nível e vimos como usá-los para personalizar os parâmetros de entrada ou cancelar completamente a operação de modificação de dados, tanto do controle Web de dados quanto dos eventos de ObjectDataSource. No próximo tutorial, veremos como criar e usar manipuladores de eventos para os eventos de nível de postagem.
Boa programação!
Sobre o autor
Scott Mitchell, autor de sete livros ASP/ASP.NET e fundador da 4GuysFromRolla.com, trabalha com tecnologias da Web da Microsoft desde 1998. Scott trabalha como consultor, instrutor e escritor independente. 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.
Agradecimentos especiais a
Esta série de tutoriais foi revisada por muitos revisores úteis. Os principais revisores deste tutorial foram Jackie Goor e Liz Shulok. Interessado em revisar meus próximos artigos do MSDN? Em caso afirmativo, envie-me uma mensagem para mitchell@4GuysFromRolla.com.