Observação
O acesso a essa página exige autorização. Você pode tentar entrar ou alterar diretórios.
O acesso a essa página exige autorização. Você pode tentar alterar os diretórios.
por Scott Mitchell
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:
- Adicione o controle Web ao
EditItemTemplate. - Use a sintaxe de vinculação de dados para atribuir o valor do campo de dados correspondente à propriedade apropriada.
- No manipulador de
UpdateCommandeventos, 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).
Figura 1: a interface de edição inclui uma Caixa de Texto, Duas Listas Suspensas e uma Caixa de Seleção (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).
Figura 2: Defina as guias UPDATE, INSERT e DELETE como Nenhum na lista Drop-Down (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.
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 IDCategories.
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 CategoriesBLL classe (consulte a GetCategories() 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.
Figura 5: Criar um Novo ObjectDataSource Nomeado CategoriesDataSource (Clique para exibir imagem em tamanho real)
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>
Figura 7: A interface de edição é definida como a interface Read-Only (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.
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.
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 BLL e DAL-Level 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 ProductsCategoryID 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 as colunas CategoryID ou SupplierID, receberemos uma mensagem de erro ArgumentOutOfRangeException semelhante a: 'Categories' tem um SelectedValue que é inválido porque ele não existe na lista de itens. Além disso, atualmente não há como alterar a categoria ou o valor de fornecedor de um produto de um valor não-NULL 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 NULLListItem 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 NULLListItem for selecionado.
Reserve um momento para ver nosso progresso por meio de um navegador. Ao editar um produto, observe que o e Categories DropDownLists Suppliers têm uma opção (None) no início do DropDownList.
Figura 10: A opção Categories e Suppliers DropDownLists incluem uma opção (Nenhum) (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 Microsoft Web 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 alcançado em mitchell@4GuysFromRolla.com.
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? Se assim for, deixe-me uma linha em mitchell@4GuysFromRolla.com.