Partilhar via


Personalizar a interface de edição do DataList (VB)

por Scott Mitchell

Baixar PDF

Neste tutorial, criaremos uma interface de edição mais avançada para o DataList, que inclui DropDownLists e um CheckBox.

Introdução

A marcação e os controles Web no DataList definem EditItemTemplate sua interface editável. Em todos os exemplos editáveis de DataList que examinamos até agora, a interface editável foi composta de controles Web TextBox. No tutorial anterior, melhoramos a experiência do usuário em tempo de edição adicionando controles de validação.

O EditItemTemplate pode ser expandido ainda mais para incluir controles Web diferentes do TextBox, como DropDownLists, RadioButtonLists, Calendars e assim por diante. Assim como acontece com TextBoxes, ao personalizar a interface de edição para incluir outros controles Web, empregue as seguintes etapas:

  1. Adicione o controle Web ao EditItemTemplate.
  2. Use a sintaxe de vinculação de dados para atribuir o valor do campo de dados correspondente à propriedade apropriada.
  3. No manipulador de UpdateCommand eventos, acesse programaticamente o valor do controle Web e passe-o para o método BLL apropriado.

Neste tutorial, criaremos uma interface de edição mais avançada para o DataList, que inclui DropDownLists e um CheckBox. Em particular, criaremos uma DataList que lista as informações do produto e permite que o nome, o fornecedor, a categoria e o status descontinuado do produto sejam atualizados (consulte a Figura 1).

A interface de edição inclui um TextBox, dois DropDownLists e um CheckBox

Figura 1: A interface de edição inclui um TextBox, dois DropDownLists e um CheckBox (clique para exibir a imagem em tamanho real)

Etapa 1: Exibindo informações do produto

Antes de criarmos a interface editável da DataList, primeiro precisamos criar a interface somente leitura. Comece abrindo a CustomizedUI.aspx página da EditDeleteDataList pasta e, no Designer, adicione uma DataList à página, definindo sua ID propriedade como Products. Na marca inteligente da DataList , crie um novo ObjectDataSource. Nomeie esse novo ObjectDataSource ProductsDataSource e configure-o para recuperar dados do ProductsBLL método da GetProducts classe. Assim como nos tutoriais editáveis anteriores da Lista de Dados, atualizaremos as informações do produto editado indo diretamente para a Camada Lógica de Negócios. Assim, defina as listas suspensas nas guias UPDATE, INSERT e DELETE como (Nenhum).

Defina as listas suspensas das guias UPDATE, INSERT e DELETE como (Nenhum)

Figura 2: Defina as listas suspensas das guias UPDATE, INSERT e DELETE como (Nenhum) (clique para exibir a imagem em tamanho real)

Depois de configurar o ObjectDataSource, o Visual Studio criará um padrão ItemTemplate para o DataList que lista o nome e o valor de cada um dos campos de dados retornados. Modifique o ItemTemplate para que o modelo liste o nome do produto em um <h4> elemento junto com o nome da categoria, o nome do fornecedor, o preço e o status descontinuado. Além disso, adicione um botão Editar, certificando-se de que sua CommandName propriedade esteja definida como Editar. A marcação declarativa para my ItemTemplate segue:

<ItemTemplate>
    <h4>
        <asp:Label ID="ProductNameLabel" runat="server"
            Text='<%# Eval("ProductName") %>' />
    </h4>
    <table border="0">
        <tr>
            <td class="ProductPropertyLabel">Category:</td>
            <td class="ProductPropertyValue">
                <asp:Label ID="CategoryNameLabel" runat="server"
                    Text='<%# Eval("CategoryName") %>' />
            </td>
            <td class="ProductPropertyLabel">Supplier:</td>
            <td class="ProductPropertyValue">
                <asp:Label ID="SupplierNameLabel" runat="server"
                    Text='<%# Eval("SupplierName") %>' />
            </td>
        </tr>
        <tr>
            <td class="ProductPropertyLabel">Discontinued:</td>
            <td class="ProductPropertyValue">
                <asp:Label ID="DiscontinuedLabel" runat="server"
                    Text='<%# Eval("Discontinued") %>' />
            </td>
            <td class="ProductPropertyLabel">Price:</td>
            <td class="ProductPropertyValue">
                <asp:Label ID="UnitPriceLabel" runat="server"
                    Text='<%# Eval("UnitPrice", "{0:C}") %>' />
            </td>
        </tr>
        <tr>
            <td colspan="4">
                <asp:Button runat="Server" ID="EditButton"
                    Text="Edit" CommandName="Edit" />
            </td>
        </tr>
    </table>
    <br />
</ItemTemplate>

A marcação acima apresenta as informações do produto usando um <título h4> para o nome do produto e quatro colunas <table> para os campos restantes. As ProductPropertyLabel classes e ProductPropertyValue CSS, definidas em Styles.css, foram discutidas em tutoriais anteriores. A Figura 3 mostra nosso progresso quando visualizado por meio de um navegador.

O nome, fornecedor, categoria, status descontinuado e preço de cada produto são exibidos

Figura 3: O nome, o fornecedor, a categoria, o status descontinuado e o preço de cada produto são exibidos (clique para exibir a imagem em tamanho real)

Etapa 2: Adicionando os controles da Web à interface de edição

A primeira etapa na criação da interface de edição personalizada do DataList é adicionar os controles da Web necessários ao EditItemTemplate. Em particular, precisamos de um DropDownList para a categoria, outro para o fornecedor e um CheckBox para o estado descontinuado. Como o preço do produto não é editável neste exemplo, podemos continuar exibindo-o usando um controle Web de Rótulo.

Para personalizar a interface de edição, clique no link Editar Modelos da marca inteligente da DataList e escolha a EditItemTemplate opção na lista suspensa. Adicione um DropDownList ao EditItemTemplate e defina como ID Categories.

Adicionar um DropDownList para as categorias

Figura 4: Adicionar um DropDownList para as categorias (clique para exibir a imagem em tamanho real)

Em seguida, na marca inteligente DropDownList , selecione a opção Escolher Fonte de Dados e crie um novo ObjectDataSource chamado CategoriesDataSource. Configure esse ObjectDataSource para usar o método da GetCategories() classe (consulte a CategoriesBLL Figura 5). Em seguida, o Assistente de Configuração de Fonte de Dados DropDownList solicita os campos de dados a serem usados para cada ListItem s Text e Value propriedades. Faça com que o DropDownList exiba o CategoryName campo de dados e use o CategoryID como o valor, conforme mostrado na Figura 6.

Criar um novo ObjectDataSource chamado CategoriesDataSource

Figura 5: Criar um novo ObjectDataSource nomeado CategoriesDataSource (clique para exibir a imagem em tamanho completo)

Configurar os campos de exibição e valor do DropDownList

Figura 6: Configurar os campos de exibição e valor do DropDownList (clique para exibir a imagem em tamanho real)

Repita esta série de etapas para criar um DropDownList para os fornecedores. Defina para ID este DropDownList como Suppliers e nomeie seu ObjectDataSource SuppliersDataSource.

Depois de adicionar os dois DropDownLists, adicione um CheckBox para o estado descontinuado e um TextBox para o nome do produto. Defina o ID s para CheckBox e TextBox como Discontinued e ProductName, respectivamente. Adicione um RequiredFieldValidator para garantir que o usuário forneça um valor para o nome do produto.

Por fim, adicione os botões Atualizar e Cancelar. Lembre-se de que, para esses dois botões, é imperativo que suas CommandName propriedades sejam definidas como Atualizar e Cancelar, respectivamente.

Sinta-se à vontade para criar a interface de edição como quiser. Optei por usar o mesmo layout de quatro colunas <table> da interface somente leitura, como ilustra a sintaxe declarativa e a captura de tela a seguir:

<EditItemTemplate>
    <h4>
        <asp:Label ID="ProductNameLabel" runat="server"
            Text='<%# Eval("ProductName") %>' />
    </h4>
    <table border="0">
        <tr>
            <td class="ProductPropertyLabel">Name:</td>
            <td colspan="3" class="ProductPropertyValue">
                <asp:TextBox runat="server" ID="ProductName" Width="90%" />
                <asp:RequiredFieldValidator ID="RequiredFieldValidator1"
                    ControlToValidate="ProductName"
                    ErrorMessage="You must enter a name for the product."
                    runat="server">*</asp:RequiredFieldValidator>
            </td>
        </tr>
        <tr>
            <td class="ProductPropertyLabel">Category:</td>
            <td class="ProductPropertyValue">
                <asp:DropDownList ID="Categories" runat="server"
                    DataSourceID="CategoriesDataSource"
                    DataTextField="CategoryName" DataValueField="CategoryID" />
            </td>
            <td class="ProductPropertyLabel">Supplier:</td>
            <td class="ProductPropertyValue">
                <asp:DropDownList ID="Suppliers"
                    DataSourceID="SuppliersDataSource" DataTextField="CompanyName"
                    DataValueField="SupplierID" runat="server" />
            </td>
        </tr>
        <tr>
            <td class="ProductPropertyLabel">Discontinued:</td>
            <td class="ProductPropertyValue">
                <asp:CheckBox runat="server" id="Discontinued" />
            </td>
            <td class="ProductPropertyLabel">Price:</td>
            <td class="ProductPropertyValue">
                <asp:Label ID="UnitPriceLabel" runat="server"
                    Text='<%# Eval("UnitPrice", "{0:C}") %>' />
            </td>
        </tr>
        <tr>
            <td colspan="4">
                <asp:Button runat="Server" ID="UpdateButton" CommandName="Update"
                    Text="Update" />
                 
                <asp:Button runat="Server" ID="CancelButton" CommandName="Cancel"
                    Text="Cancel" CausesValidation="False" />
            </td>
        </tr>
    </table>
    <br />
    <asp:ObjectDataSource ID="CategoriesDataSource" runat="server"
        OldValuesParameterFormatString="original_{0}" SelectMethod="GetCategories"
        TypeName="CategoriesBLL">
    </asp:ObjectDataSource>
    <asp:ObjectDataSource ID="SuppliersDataSource" runat="server"
        OldValuesParameterFormatString="original_{0}" SelectMethod="GetSuppliers"
        TypeName="SuppliersBLL">
    </asp:ObjectDataSource>
</EditItemTemplate>

A interface de edição é disposta como a interface somente leitura

Figura 7: A interface de edição é disposta como a interface somente leitura (clique para exibir a imagem em tamanho real)

Etapa 3: Criando os manipuladores de eventos EditCommand e CancelCommand

Atualmente, não há sintaxe de vinculação de EditItemTemplate dados no (exceto para o UnitPriceLabel, que foi copiado literalmente do ItemTemplate). Adicionaremos a sintaxe de vinculação de dados momentaneamente, mas primeiro vamos criar os manipuladores de eventos para os DataList s EditCommand e CancelCommand eventos. Lembre-se de que a responsabilidade do manipulador de eventos é renderizar a interface de EditCommand edição para o item DataList cujo botão Editar foi clicado, enquanto o CancelCommand trabalho do s é retornar o DataList ao seu estado de pré-edição.

Crie esses dois manipuladores de eventos e faça com que eles usem o seguinte código:

Protected Sub Products_EditCommand(source As Object, e As DataListCommandEventArgs) _
    Handles Products.EditCommand
    ' Set the DataList's EditItemIndex property to the
    ' index of the DataListItem that was clicked
    Products.EditItemIndex = e.Item.ItemIndex
    ' Rebind the data to the DataList
    Products.DataBind()
End Sub
Protected Sub Products_CancelCommand(source As Object, e As DataListCommandEventArgs) _
    Handles Products.CancelCommand
    ' Set the DataList's EditItemIndex property to -1
    Products.EditItemIndex = -1
    ' Rebind the data to the DataList
    Products.DataBind()
End Sub

Com esses dois manipuladores de eventos em vigor, clicar no botão Editar exibe a interface de edição e clicar no botão Cancelar retorna o item editado ao seu modo somente leitura. A Figura 8 mostra a DataList depois que o botão Edit foi clicado para o Chef Anton s Gumbo Mix. Como ainda não adicionamos nenhuma sintaxe de vinculação de dados à interface de edição, o ProductName TextBox está em branco, o Discontinued CheckBox desmarcado e os primeiros itens selecionados em Categories e Suppliers DropDownLists.

Captura de tela mostrando o DataList EditItemTemplate depois que os manipuladores de eventos EditCommand e CancelCommand foram adicionados e o botão Editar foi selecionado.

Figura 8: Clicar no botão Editar exibe a interface de edição (clique para exibir a imagem em tamanho real)

Etapa 4: Adicionando a sintaxe DataBinding à interface de edição

Para que a interface de edição exiba os valores atuais do produto, precisamos usar a sintaxe de vinculação de dados para atribuir os valores do campo de dados aos valores de controle da Web apropriados. A sintaxe de vinculação de dados pode ser aplicada por meio do Designer acessando a tela Editar Modelos e selecionando o link Editar DataBindings nas marcas inteligentes de controles da Web. Como alternativa, a sintaxe de vinculação de dados pode ser adicionada diretamente à marcação declarativa.

Atribua o valor do ProductName campo de dados à ProductName propriedade TextBox , Text os valores do CategoryID campo de dados e SupplierID às Categories propriedades e Suppliers DropDownLists SelectedValue e o valor do Discontinued campo de dados à Discontinued propriedade da Checked CheckBox . Depois de fazer essas alterações, seja por meio do Designer ou diretamente por meio da marcação declarativa, revisite a página por meio de um navegador e clique no botão Editar para o Gumbo Mix do Chef Anton. Como mostra a Figura 9, a sintaxe de vinculação de dados adicionou os valores atuais a TextBox, DropDownLists e CheckBox.

Captura de tela mostrando o DataList EditItemTemplate depois que a sintaxe DataBinding foi adicionada e o botão Editar foi selecionado.

Figura 9: Clicar no botão Editar exibe a interface de edição (clique para exibir a imagem em tamanho real)

Etapa 5: Salvando as alterações do usuário no manipulador de eventos UpdateCommand

Quando o usuário edita um produto e clica no botão Atualizar, ocorre um postback e o evento do UpdateCommand DataList é acionado. No manipulador de eventos, precisamos ler os valores dos controles Web na EditItemTemplate interface e com a BLL para atualizar o produto no banco de dados. Como vimos em tutoriais anteriores, o ProductID do produto atualizado é acessível por meio da DataKeys coleção. Os campos inseridos pelo usuário são acessados referenciando programaticamente os controles Web usando FindControl("controlID"), como mostra o código a seguir:

Protected Sub Products_UpdateCommand(source As Object, e As DataListCommandEventArgs) _
    Handles Products.UpdateCommand
    If Not Page.IsValid Then
        Exit Sub
    End If
    ' Read in the ProductID from the DataKeys collection
    Dim productID As Integer = Convert.ToInt32(Products.DataKeys(e.Item.ItemIndex))
    ' Read in the product name and price values
    Dim productName As TextBox = CType(e.Item.FindControl("ProductName"), TextBox)
    Dim categories As DropDownList=CType(e.Item.FindControl("Categories"), DropDownList)
    Dim suppliers As DropDownList = CType(e.Item.FindControl("Suppliers"), DropDownList)
    Dim discontinued As CheckBox = CType(e.Item.FindControl("Discontinued"), CheckBox)
    Dim productNameValue As String = Nothing
    If productName.Text.Trim().Length > 0 Then
        productNameValue = productName.Text.Trim()
    End If
    Dim categoryIDValue As Integer = Convert.ToInt32(categories.SelectedValue)
    Dim supplierIDValue As Integer = Convert.ToInt32(suppliers.SelectedValue)
    Dim discontinuedValue As Boolean = discontinued.Checked
    ' Call the ProductsBLL's UpdateProduct method...
    Dim productsAPI As New ProductsBLL()
    productsAPI.UpdateProduct(productNameValue, categoryIDValue, supplierIDValue, _
        discontinuedValue, productID)
    ' Revert the DataList back to its pre-editing state
    Products.EditItemIndex = -1
    Products.DataBind()
End Sub

O código começa consultando a Page.IsValid propriedade para garantir que todos os controles de validação na página sejam válidos. Se Page.IsValid for True, o valor do ProductID produto editado será lido da DataKeys coleção e os controles Web de entrada de dados no EditItemTemplate serão referenciados programaticamente. Em seguida, os valores desses controles Web são lidos em variáveis que são passadas para a sobrecarga apropriada UpdateProduct . Depois de atualizar os dados, o DataList é retornado ao seu estado de pré-edição.

Observação

Omiti a lógica de tratamento de exceções adicionada no tutorial Manipulando exceções de nível BLL e DAL para manter o código e este exemplo focados. Como exercício, adicione essa funcionalidade depois de concluir este tutorial.

Etapa 6: Manipulando valores NULL CategoryID e SupplierID

O banco de dados Northwind permite NULL valores para as Products CategoryID tabelas e SupplierID colunas. No entanto, nossa interface de edição atualmente não acomoda NULL valores. Se tentarmos editar um produto que tenha um NULL valor para suas CategoryID colunas ou SupplierID , receberemos uma ArgumentOutOfRangeException mensagem de erro semelhante a: 'Categorias' tem um SelectedValue que é inválido porque não existe na lista de itens. Além disso, atualmente não há como alterar a categoria de um produto ou o valor do fornecedor de um valor nãoNULL para um NULL .

Para oferecer suporte NULL a valores para a categoria e o fornecedor DropDownLists, precisamos adicionar um arquivo .ListItem Eu escolhi usar (Nenhum) como o Text valor para isso ListItem, mas você pode alterá-lo para outra coisa (como uma string vazia) se desejar. Por fim, lembre-se de definir o DropDownLists AppendDataBoundItems como True; se você esquecer de fazer isso, as categorias e os fornecedores vinculados ao DropDownList substituirão o ListItemarquivo .

Depois de fazer essas alterações, a marcação DropDownLists no DataList deve EditItemTemplate ser semelhante à seguinte:

<asp:DropDownList ID="Categories" DataSourceID="CategoriesDataSource"
    DataTextField="CategoryName" DataValueField="CategoryID"  runat="server"
    SelectedValue='<%# Eval("CategoryID") %>' AppendDataBoundItems="True">
    <asp:ListItem Value=" Selected="True">(None)</asp:ListItem>
</asp:DropDownList>
...
<asp:DropDownList ID="Suppliers" DataSourceID="SuppliersDataSource"
    DataTextField="CompanyName" DataValueField="SupplierID" runat="server"
    SelectedValue='<%# Eval("SupplierID") %>' AppendDataBoundItems="True">
    <asp:ListItem Value=" Selected="True">(None)</asp:ListItem>
</asp:DropDownList>

Observação

Os s estáticos ListItem podem ser adicionados a um DropDownList por meio do Designer ou diretamente por meio da sintaxe declarativa. Ao adicionar um item DropDownList para representar um valor de banco de dados NULL , certifique-se de adicionar o por meio da ListItem sintaxe declarativa. Se você usar o Editor de ListItem Coleção no Designer, a sintaxe declarativa gerada omitirá a Value configuração completamente quando atribuída uma string em branco, criando uma marcação declarativa como: <asp:ListItem>(None)</asp:ListItem>. Embora isso possa parecer inofensivo, a falta Value faz com que o DropDownList use o valor da Text propriedade em seu lugar. Isso significa que, se essa opção NULL ListItem for selecionada, o valor (Nenhum) será tentado a ser atribuído ao campo de dados do produto (CategoryID ou SupplierID, neste tutorial), o que resultará em uma exceção. Ao definir Value=""explicitamente , um NULL valor será atribuído ao campo de dados do produto quando o NULL ListItem for selecionado.

Reserve um momento para ver nosso progresso por meio de um navegador. Ao editar um produto, observe que o e Suppliers DropDownLists Categories têm uma opção (None) no início do DropDownList.

As Listas Suspensas de Categorias e Fornecedores incluem uma opção (Nenhuma)

Figura 10: As e Suppliers DropDownLists Categories incluem uma opção (Nenhuma) (clique para exibir a imagem em tamanho real)

Para salvar a opção (None) como um valor de banco de dados NULL , precisamos retornar ao manipulador de UpdateCommand eventos. Altere as categoryIDValue variáveis e supplierIDValue para serem inteiros anuláveis e atribua a elas um valor diferente de Nothing somente se o DropDownList não SelectedValue for uma cadeia de caracteres vazia:

Dim categoryIDValue As Nullable(Of Integer) = Nothing
If Not String.IsNullOrEmpty(categories.SelectedValue) Then
    categoryIDValue = Convert.ToInt32(categories.SelectedValue)
End If
Dim supplierIDValue As Nullable(Of Integer) = Nothing
If Not String.IsNullOrEmpty(suppliers.SelectedValue) Then
    supplierIDValue = Convert.ToInt32(suppliers.SelectedValue)
End If

Com essa alteração, um valor de Nothing será passado para o UpdateProduct método BLL se o usuário selecionou a opção (Nenhum) em qualquer uma das listas suspensas, que corresponde a um NULL valor de banco de dados.

Resumo

Neste tutorial, vimos como criar uma interface de edição DataList mais complexa que incluía três controles Web de entrada diferentes: um TextBox, dois DropDownLists e um CheckBox, juntamente com controles de validação. Ao criar a interface de edição, as etapas são as mesmas, independentemente dos controles da Web que estão sendo usados: comece adicionando os controles da Web aos DataList EditItemTemplate; use a sintaxe de vinculação de dados para atribuir os valores de campo de dados correspondentes com as propriedades de controle da Web apropriadas; e, no manipulador de UpdateCommand eventos, acesse programaticamente os controles da Web e suas propriedades apropriadas, passando seus valores para a BLL.

Ao criar uma interface de edição, seja ela composta apenas por TextBoxes ou uma coleção de controles Web diferentes, certifique-se de lidar corretamente com os valores do banco de dados NULL . Ao contabilizar NULL s, é imperativo que você não apenas exiba corretamente um valor existente NULL na interface de edição, mas também que ofereça um meio de marcar um valor como NULL. Para DropDownLists em DataLists, isso normalmente significa adicionar um estático ListItem cuja Value propriedade é explicitamente definida como uma cadeia de caracteres vazia (Value="") e adicionar um pouco de código ao UpdateCommand manipulador de eventos para determinar se o NULL``ListItem foi selecionado ou não.

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 Dennis Patterson, David Suru e Randy Schmidt. Interessado em revisar meus próximos artigos do MSDN? Em caso afirmativo, envie-me uma mensagem para mitchell@4GuysFromRolla.com.