Personalizar a interface de edição do DataList (VB)
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
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).
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).
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.
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
.
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.
Figura 5: Criar um novo ObjectDataSource nomeado CategoriesDataSource
(clique para exibir a imagem em tamanho completo)
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 é 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.
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 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 ListItem
arquivo .
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.
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.