Examinar os eventos associados à inserção, atualização e exclusão (VB)

por Scott Mitchell

Baixar PDF

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, uma variedade de etapas ocorre 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 atualizar os dados e clicar em Atualizar, as seguintes etapas serão executadas no postback:

  1. O GridView preenche seu ObjectDataSource UpdateParameters com os campos de identificação exclusivos do registro editado (por meio da DataKeyNames propriedade) juntamente com os valores inseridos pelo usuário
  2. O GridView invoca o método objectDataSource Update() , que, por sua vez, invoca o método apropriado no objeto subjacente (ProductsDAL.UpdateProduct, em nosso tutorial anterior)
  3. Os dados subjacentes, que agora incluem as alterações atualizadas, são recuperados para o GridView

Durante essa sequência de etapas, vários eventos são acionados, permitindo que criemos manipuladores de eventos para adicionar lógica personalizada quando necessário. Por exemplo, antes da Etapa 1, o evento gridView é RowUpdating acionado. Podemos, neste ponto, cancelar a solicitação de atualização se houver algum erro de validação. Quando o Update() método é invocado, o evento objectDataSource é Updating acionado, fornecendo uma oportunidade para adicionar ou personalizar os valores de qualquer um dos UpdateParameters. Depois que o método do objeto subjacente objectDataSource for concluído em execução, o evento objectDataSource será Updated 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 gridView RowUpdated é acionado; um manipulador de 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 esta série de eventos e etapas ao atualizar um GridView. O padrão de evento na Figura 1 não é exclusivo para atualização com um GridView. Inserir, atualizar ou excluir dados do GridView, DetailsView ou FormView precipita a mesma sequência de eventos pré e pós-nível para o controle da Web de dados e o ObjectDataSource.

Uma série de pré e pós-eventos é disparada ao atualizar dados em um GridView

Figura 1: Uma série de pré e pós-eventos é disparada 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 da 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 campos eUnitPriceprodutosProductName

Nas interfaces de edição do tutorial anterior , todos os campos de produto que não eram somente leitura tinham que ser incluídos. Se fôssemos remover um campo do GridView - digamos QuantityPerUnit - ao atualizar os dados, o controle da Web de dados não definiria o valor do QuantityPerUnitUpdateParameters ObjectDataSource. Em seguida, o ObjectDataSource passaria um valor de Nothing para o UpdateProduct método BLL (Camada de Lógica de Negócios), que alteraria a coluna do registro de banco de QuantityPerUnit dados editado para um NULL valor. Da mesma forma, se um campo necessário, como ProductName, for removido da interface de edição, a atualização falhará com uma exceção "ProductName" da coluna não permitirá nulos. O motivo desse comportamento foi porque 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 objectDataSource UpdateParameters 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, precisamos definir programaticamente os valores ausentes UpdateParameters no manipulador de eventos do Updating ObjectDataSource ou criar e chamar um método BLL que espera apenas um subconjunto dos campos. Vamos explorar essa última abordagem.

Especificamente, vamos criar uma página que exibe 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 exibidos e ProductNameUnitPrice. 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 UpdateProduct BLL existente e tenha os valores de campo de produto ausentes definidos programaticamente em seu Updating manipulador de eventos ou precisamos criar um novo método BLL que espera apenas o subconjunto de campos definidos no GridView. Para este tutorial, vamos usar a última opção e criar uma sobrecarga do UpdateProduct método , uma que usa apenas três parâmetros de entrada: productName, unitPricee 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

Assim como o método original UpdateProduct , essa sobrecarga começa verificando se há um produto no banco de dados com o especificado ProductID. Caso contrário, retornará False, indicando que a solicitação para atualizar as informações do produto falhou. Caso contrário, ele atualiza os campos e UnitPrice do registro de ProductName produto existentes adequadamente e confirma a atualização chamando o método tableAdapterUpdate(), passando a ProductsRow instância.

Com essa adição à nossa ProductsBLL classe, estamos prontos para criar a interface simplificada do GridView. Abra na DataModificationEvents.aspxEditInsertDelete pasta e adicione um GridView à página. Crie um novo ObjectDataSource e configure-o para usar a classe com seu ProductsBLLSelect() mapeamento de método para GetProducts e seu Update() mapeamento de método para a UpdateProduct sobrecarga que usa apenas os productNameparâmetros de entrada , unitPricee productID . A Figura 2 mostra o assistente Criar Fonte de Dados ao mapear o método ObjectDataSource Update() para a ProductsBLL sobrecarga do novo UpdateProduct método da classe.

Mapear o método Update() do ObjectDataSource para a Sobrecarga de Novo UpdateProduct

Figura 2: mapear o método ObjectDataSource Update() para a nova UpdateProduct sobrecarga (clique para exibir a imagem em tamanho real)

Como nosso exemplo inicialmente só precisará da capacidade de editar dados, mas não inserir ou excluir registros, reserve um momento para indicar explicitamente que os métodos e Delete() objectDataSource Insert() 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.

Escolha (Nenhum) na lista de Drop-Down para as guias INSERT e DELETE

Figura 3: Escolha (Nenhum) na lista Drop-Down para as guias INSERT e DELETE (Clique para exibir a imagem em tamanho real)

Depois de concluir esse assistente marcar a caixa de seleção Habilitar Edição da marca inteligente gridView.

Com a conclusão do assistente Criar Fonte de Dados e associar isso ao GridView, o Visual Studio criou a sintaxe declarativa para ambos os controles. Vá para o modo de exibição Origem 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 métodos e Delete() ObjectDataSourceInsert(), não há seções InsertParameters ou 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 ObjectDataSource OldValuesParameterFormatString está 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 do janela Propriedades na exibiçã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, do 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.

O GridView contém um BoundField ou CheckBoxField 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 objectDataSource UpdateParameters para 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, ObjectDataSource acabará invocando a UpdateProduct sobrecarga que recebe 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 correspondam aos parâmetros de entrada para uma UpdateProduct sobrecarga, uma exceção será gerada ao tentar atualizar.

O GridView adicionará parâmetros à coleção UpdateParameters do ObjectDataSource

Figura 5: o GridView adicionará parâmetros à coleção objectDataSource UpdateParameters (clique para exibir a imagem em tamanho real)

Para garantir que o ObjectDataSource invoque a UpdateProduct sobrecarga que usa 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 Trueou por alguma combinação dos dois. Para este tutorial, vamos simplesmente remover todos os campos gridview, exceto o ProductName e UnitPrice BoundFields, 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 pelo 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 de produto.

A interface permite a edição apenas do nome e do preço do produto

Figura 6: a interface permite a edição apenas do nome e do 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 GridView EnableViewState como false, correrá o risco de ter usuários simultâneos excluindo ou editando registros involuntariamente.

Melhorando aUnitPriceformatação

Embora o exemplo GridView mostrado na Figura 6 funcione, o UnitPrice campo não é formatado, resultando em uma exibição de preço que não tem símbolos de moeda e tem quatro casas decimais. Para aplicar uma formatação de moeda para as linhas não editáveis, basta definir a UnitPrice propriedade {0:c} BoundField DataFormatString como e sua HtmlEncode propriedade como False.

Defina as propriedades DataFormatString e HtmlEncode do UnitPrice de acordo

Figura 7: Definir as UnitPricepropriedades e HtmlEncode 's DataFormatString adequadamente (clique para exibir a imagem em tamanho real)

Com essa alteração, as linhas não editáveis formatarão 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.

As linhas não editáveis agora são formatadas como valores de Conversor de Moedas

Figura 8: As linhas não editáveis agora são formatadas como valores de Conversor de Moedas (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 True BoundField ApplyFormatInEditMode como (o padrão é False). Reserve um momento para definir essa propriedade como True.

Definir a propriedade ApplyFormatInEditMode de UnitPrice BoundField como True

Figura 9: definir a UnitPrice propriedade BoundField ApplyFormatInEditMode como True (Clique para exibir a imagem em tamanho real)

Com essa alteração, o valor do UnitPrice exibido na linha editada também é formatado como uma moeda.

Captura de tela do GridView mostrando o valor UnitPrice da linha editada formatada como uma moeda.

Figura 10: o valor da UnitPrice linha editada agora está formatado como um Conversor de Moedas (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, lança um FormatException. Quando o GridView tenta atribuir os valores fornecidos pelo usuário à coleção objectDataSource UpdateParameters , não é possível converter a UnitPrice cadeia de caracteres "$19.00" no Decimal exigido pelo parâmetro (consulte Figura 11). Para corrigir isso, podemos criar um manipulador de eventos para o evento gridview RowUpdating e fazer com que ele analise o fornecido pelo UnitPrice usuário como um formato Decimalde moeda .

O evento gridview RowUpdating aceita como seu segundo parâmetro um objeto do tipo GridViewUpdateEventArgs, que inclui um dicionário como uma NewValues de suas propriedades que contém os valores fornecidos pelo usuário prontos para serem atribuídos à coleção objectDataSource UpdateParameters . Podemos substituir o valor existente UnitPrice na NewValues 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 "$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 pelo UnitPriceusuário, juntamente com como o manipulador de eventos do RowUpdating GridView pode ser utilizado para analisar corretamente essa entrada.

Diagrama mostrando como o ObjectDataSource processa o campo UnitPrice e como o manipulador de eventos RowUpdate do GridView converte uma cadeia de caracteres em um decimal.

Figura 11: o valor da UnitPrice linha editada agora está formatado como um Conversor de Moedas (Clique para exibir a imagem em tamanho real)

Etapa 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 NULLUnitPrice valor. Ou seja, se um usuário não digitar um UnitPrice valor ao editar uma linha do produto, em vez de salvar os resultados no banco de dados, queremos exibir uma mensagem informando ao usuário que, por meio desta 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 Truee.Cancel como e exibir uma mensagem explicando por que se o UnitPrice valor na NewValues coleção tem um valor de Nothing.

Comece adicionando um controle Web De rótulo à página chamada MustProvideUnitPriceMessage. Esse controle 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 no Styles.css nome Warning com 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.

Um rótulo foi adicionado acima do GridView

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 Page_Load manipulador de 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, queremos cancelar a atualização e exibir o rótulo de aviso. Aumente o manipulador de eventos do GridView da RowUpdating 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) permitam NULLUnitPrice s, essa página de ASP.NET específica não permite.

Um usuário não pode deixar UnitPrice em branco

Figura 13: Um usuário não pode deixar UnitPrice em branco (clique para exibir imagem em tamanho real)

Até agora, vimos como usar o evento gridview RowUpdating para alterar programaticamente os valores de parâmetro atribuídos à coleção do UpdateParameters ObjectDataSource, bem como cancelar o processo de atualização completamente. 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 Insertingeventos , Updatinge Deleting . Esses eventos são acionados antes que o método associado do objeto subjacente seja invocado e forneçam uma oportunidade de última chance para modificar a coleção de parâmetros de entrada ou cancelar a operação imediatamente. Os manipuladores de eventos para esses três eventos são passados por 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 InsertParameters, UpdateParametersou DeleteParameters, dependendo se o manipulador de eventos é para o Insertingevento , Updatingou Deleting

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. Este DetailsView será usado para fornecer uma interface para adicionar rapidamente um novo produto ao banco de dados. Para manter uma interface do 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 ObjectDataSource Inserting 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 e 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 este DetailsView para adicionar novos produtos, precisamos marcar a opção Habilitar Inserção da marca inteligente; no entanto, não há essa opção porque o método objectDataSource Insert() não é mapeado para um método na ProductsBLL classe (lembre-se de que definimos esse mapeamento como (Nenhum) ao configurar a fonte de dados, consulte Figura 3).

Para configurar o ObjectDataSource, selecione o link Configurar Fonte de Dados de sua marca inteligente, iniciando o assistente. A primeira tela permite que você altere o objeto subjacente ao qual ObjectDataSource está associado; 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ê acessar as guias INSERT e DELETE, verá que um mapeamento está lá. Isso ocorre porque os ProductsBLLmétodos e DeleteProduct usam AddProduct 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).

Definir a lista de Drop-Down da guia INSERT como o método AddProduct

Figura 14: definir a lista de Drop-Down da guia INSERT como o AddProduct método (clique para exibir a imagem em tamanho real)

Definir a lista de Drop-Down da guia DELETE como (Nenhum)

Figura 15: definir a lista de Drop-Down da guia DELETE como (Nenhum) (Clique para exibir a imagem em tamanho real)

Depois de fazer essas alterações, a sintaxe declarativa do ObjectDataSource será expandida para incluir uma coleção InsertParameters , 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 a OldValuesParameterFormatString propriedade . Tire 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 detailsView agora incluirá a caixa de seleção Habilitar Inserção; retorne ao Designer e marcar essa opção. Em seguida, pare 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 exibida por meio de um navegador neste ponto. 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 fornece um meio para o usuário adicionar rapidamente um novo produto ao banco de dados.

O DetailsView é renderizado no momento no modo Read-Only

Figura 16: O DetailsView é renderizado atualmente no modo Read-Only (Clique para exibir a imagem em tamanho real)

Para mostrar o DetailsView no 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á depois de inserir um novo registro. Como mostra a Figura 17, tal DetailsView fornece uma interface rápida para adicionar um novo registro.

O DetailsView fornece uma interface para adicionar rapidamente um novo produto

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 de produto e um preço (como "Acme Water" e 1,99, como na Figura 17) e clica em Inserir, um postback se segue e o fluxo de trabalho de inserção começa, culminando em um novo registro de produto sendo adicionado ao banco de dados. O DetailsView mantém sua interface de inserção e o GridView é automaticamente recuperado para sua fonte de dados para incluir o novo produto, conforme mostrado na Figura 18.

O Produto

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 CategoryIDDetailsView , SupplierID, QuantityPerUnite assim por diante são valores de banco de dados atribuídos NULL . Você pode ver isso executando as seguintes etapas:

  1. Ir para a Explorer do Servidor no Visual Studio
  2. Expandindo o nó do NORTHWND.MDF banco de dados
  3. Clique com o botão direito do mouse no nó da tabela de Products banco de dados
  4. Selecione Mostrar Dados da Tabela

Isso listará todos os registros na Products tabela. Como mostra a Figura 19, todas as colunas do novo produto que ProductIDnão sejam , ProductNamee UnitPrice têm NULL valores.

Os campos do produto não fornecidos no DetailsView são valores NULL atribuídos

Figura 19: Os campos do produto não fornecidos no DetailsView são Valores Atribuídos NULL (clique para exibir a imagem em tamanho real)

Talvez queiramos fornecer um valor padrão diferente NULL de um ou mais desses valores de coluna, porque NULL não é a melhor opção padrão ou porque a própria coluna de banco de dados não permite NULL s. Para fazer isso, podemos definir programaticamente os valores dos parâmetros da coleção detailsview InputParameters . Essa atribuição pode ser feita no manipulador de eventos do evento DetailsView ItemInserting ou no evento ObjectDataSource Inserting . Como já examinamos o uso dos eventos pré e pós-nível no nível de controle da Web de dados, vamos explorar usando os eventos do ObjectDataSource desta vez.

Etapa 4: Atribuindo valores aosCategoryIDparâmetros eSupplierID

Para este tutorial, vamos imaginar que para nosso aplicativo ao adicionar um novo produto por meio dessa interface, ele deve ser atribuído um CategoryID valor e SupplierID de 1. Conforme mencionado anteriormente, o ObjectDataSource tem um par de eventos 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, em seguida, chama o método para o qual seu Insert() método foi mapeado e, finalmente, gera o Inserted evento. O Inserting manipulador de eventos oferece uma última oportunidade para 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 especificasse a categoria e o fornecedor ou escolheria 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 eventos para o evento objectDataSource Inserting . 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 objectDataSource InsertParameters com os valores atribuídos de DetailsView. Para alterar o valor de um desses parâmetros, basta usar: e.InputParameters("paramName") = value. Portanto, para definir os CategoryID valores e SupplierID como 1, ajuste o Inserting manipulador de eventos para ter a seguinte aparência:

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

Novos produtos agora têm seus valores CategoryID e SupplierID definidos como 1

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 da Web de dados e o ObjectDataSource prossseguem em vários eventos 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 a operação de modificação de dados completamente dos eventos do controle da Web de dados e do ObjectDataSource. No próximo tutorial, examinaremos a criação e o uso de manipuladores de eventos para os eventos de pós-nível.

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.

Agradecimentos Especiais

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? Nesse caso, deixe-me uma linha em mitchell@4GuysFromRolla.com.