Personalizar a interface de edição do DataList (C#)
por Scott Mitchell
Neste tutorial, criaremos uma interface de edição mais avançada para DataList, uma que inclui DropDownLists e uma CheckBox.
Introdução
A marcação e os controles da Web nos DataLists EditItemTemplate
definem sua interface editável. Em todos os exemplos editáveis de DataList que examinamos até agora, a interface editável foi composta por controles da 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 da 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 da Web, empregue as seguintes etapas:
- Adicione o controle da Web ao
EditItemTemplate
. - Use a sintaxe de associação de dados para atribuir o valor do campo de dados correspondente à propriedade apropriada.
UpdateCommand
No manipulador de eventos, acesse programaticamente o valor de controle da Web e passe-o para o método BLL apropriado.
Neste tutorial, criaremos uma interface de edição mais avançada para DataList, uma que inclui DropDownLists e uma CheckBox. Em particular, criaremos uma DataList que lista as informações do produto e permite que o nome, o fornecedor, a categoria e os status descontinuados do produto sejam atualizados (consulte a Figura 1).
Figura 1: a interface de edição inclui uma TextBox, duas DropDownLists e uma CheckBox (clique para exibir a imagem em tamanho real)
Etapa 1: Exibindo informações do produto
Antes de podermos criar a interface editável do DataList, primeiro precisamos criar a interface somente leitura. Comece abrindo a CustomizedUI.aspx
página da EditDeleteDataList
pasta e, no Designer, adicione um DataList à página, definindo sua ID
propriedade como Products
. Na marca inteligente DataList, crie um novo ObjectDataSource. Nomeie esse novo ObjectDataSource ProductsDataSource
e configure-o para recuperar dados do método s da ProductsBLL
GetProducts
classe. Assim como nos tutoriais anteriores editáveis do DataList, atualizaremos as informações do produto editado acessando diretamente a Camada de Lógica de Negócios. Assim, defina as listas suspensas nas guias UPDATE, INSERT e DELETE como (Nenhum).
Figura 2: Definir as guias UPDATE, INSERT e DELETE Drop-Down Listas como (Nenhum) (Clique para exibir a imagem em tamanho real)
Depois de configurar o ObjectDataSource, o Visual Studio criará um padrão ItemTemplate
para 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 juntamente com o nome da categoria, o nome do fornecedor, o preço e os status descontinuados. Além disso, adicione um botão Editar, certificando-se de que sua CommandName
propriedade esteja definida como Editar. A marcação declarativa para a seguinte ItemTemplate
:
<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 dispõe as informações do produto usando um <título h4> para o nome do produto e uma de 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 exibido 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: Adicionar os controles da Web à interface de edição
A primeira etapa na criação da interface de edição datalist personalizada é adicionar os controles da Web necessários ao EditItemTemplate
. Em particular, precisamos de um DropDownList para a categoria, outro para o fornecedor e uma 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 label.
Para personalizar a interface de edição, clique no link Editar Modelos da marca inteligente DataList e escolha a opção EditItemTemplate
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 este ObjectDataSource para usar o CategoriesBLL
método da classe s GetCategories()
(consulte a Figura 5). Em seguida, o Assistente de Configuração da Fonte de Dados dropDownList solicita que os campos de dados sejam usados para cada ListItem
s Text
e Value
propriedades. Fazer 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 objetoDataSource nomeado CategoriesDataSource
(clique para exibir a imagem em tamanho real)
Figura 6: Configurar os campos 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 o ID
para este DropDownList como Suppliers
e nomeie seu ObjectDataSource SuppliersDataSource
.
Depois de adicionar as duas DropDownLists, adicione uma CheckBox para o estado descontinuado e uma TextBox para o nome do produto. Defina os 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.
Fique à vontade para definir a interface de edição como desejar. 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" DataTextField="CompanyName"
DataSourceID="SuppliersDataSource"
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 de 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 associação de dados no EditItemTemplate
(exceto para o UnitPriceLabel
, que foi copiado textualmente do ItemTemplate
). Adicionaremos a sintaxe de vinculação de dados momentaneamente, mas primeiro vamos criar os manipuladores de eventos para os eventos e CancelCommand
DataListEditCommand
. Lembre-se de que a responsabilidade do manipulador de EditCommand
eventos é renderizar a interface de edição para o item DataList cujo botão Editar foi clicado, enquanto o CancelCommand
trabalho do s é retornar a DataList para seu estado de pré-edição.
Crie esses dois manipuladores de eventos e use o seguinte código:
protected void Products_EditCommand(object source, DataListCommandEventArgs e)
{
// Set the DataList's EditItemIndex property and rebind the data
Products.EditItemIndex = e.Item.ItemIndex;
Products.DataBind();
}
protected void Products_CancelCommand(object source, DataListCommandEventArgs e)
{
// Return to DataList to its pre-editing state
Products.EditItemIndex = -1;
Products.DataBind();
}
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 para seu modo somente leitura. A Figura 8 mostra o DataList depois que o botão Editar é clicado para o Gumbo Mix do Chef Anton. Como ainda não adicionamos nenhuma sintaxe de associação de dados à interface de edição, a ProductName
TextBox está em branco, a Discontinued
Caixa de Seleção desmarcada e os primeiros itens selecionados nas Categories
listas 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 associação de dados para atribuir os valores de 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 s Text
, aos CategoryID
valores do campo de dados e SupplierID
às Categories
propriedades e Suppliers
DropDownLists SelectedValue
e o valor do Discontinued
campo de dados à Discontinued
propriedade s Checked
CheckBox. Depois de fazer essas alterações, por meio do Designer ou diretamente por meio da marcação declarativa, reveja 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 associação de dados adicionou os valores atuais ao 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: salvar 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 DataList é UpdateCommand
acionado. No manipulador de eventos, precisamos ler os valores dos controles da Web na EditItemTemplate
interface e com a BLL para atualizar o produto no banco de dados. Como vimos nos 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 da Web usando FindControl("controlID")
, como mostra o seguinte código:
protected void Products_UpdateCommand(object source, DataListCommandEventArgs e)
{
// Make sure the page is valid...
if (!Page.IsValid)
return;
// Read in the ProductID from the DataKeys collection
int productID = Convert.ToInt32(Products.DataKeys[e.Item.ItemIndex]);
// Read in the product name and price values
TextBox productName = (TextBox)e.Item.FindControl("ProductName");
DropDownList categories = (DropDownList)e.Item.FindControl("Categories");
DropDownList suppliers = (DropDownList)e.Item.FindControl("Suppliers");
CheckBox discontinued = (CheckBox)e.Item.FindControl("Discontinued");
string productNameValue = null;
if (productName.Text.Trim().Length > 0)
productNameValue = productName.Text.Trim();
int categoryIDValue = Convert.ToInt32(categories.SelectedValue);
int supplierIDValue = Convert.ToInt32(suppliers.SelectedValue);
bool discontinuedValue = discontinued.Checked;
// Call the ProductsBLL's UpdateProduct method...
ProductsBLL productsAPI = new ProductsBLL();
productsAPI.UpdateProduct(productNameValue, categoryIDValue, supplierIDValue,
discontinuedValue, productID);
// Revert the DataList back to its pre-editing state
Products.EditItemIndex = -1;
Products.DataBind();
}
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 produto editado será ProductID
lido da DataKeys
coleção e os controles da Web de entrada de dados no EditItemTemplate
serão referenciados programaticamente. Em seguida, os valores desses controles da 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 de CategoryID e SupplierID NULL
O banco de dados Northwind permite NULL
valores para as Products
colunas e SupplierID
da CategoryID
tabela. 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
, obteremos um com uma ArgumentOutOfRangeException
mensagem de erro 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 do fornecedor de um produto de um valor nãoNULL
para um NULL
.
Para dar suporte NULL
a valores para a categoria e o fornecedor DropDownLists, precisamos adicionar um adicional ListItem
. Optei por usar (Nenhum) como o Text
valor para este ListItem
, mas você pode alterá-lo para outra coisa (como uma cadeia de caracteres vazia) se desejar. Por fim, lembre-se de definir DropDownLists AppendDataBoundItems
como True
; se você esquecer de fazer isso, as categorias e fornecedores associados ao DropDownList substituirão o adicionado estaticamente ListItem
.
Depois de fazer essas alterações, a marcação DropDownLists nas Listas de Dados EditItemTemplate
deve 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
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
, adicione o ListItem
por meio da sintaxe declarativa. Se você usar o ListItem
Editor Coleção no Designer, a sintaxe declarativa gerada omitirá a Value
configuração completamente quando for atribuída uma cadeia de caracteres em branco, criando marcação declarativa como: <asp:ListItem>(None)</asp:ListItem>
. Embora isso possa parecer inofensivo, o ausente Value
faz com que o DropDownList use o valor da Text
propriedade em seu lugar. Isso significa que, se isso NULL
ListItem
for selecionado, o valor (Nenhum) tentará 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 e DropDownLists têm uma opção Categories
Suppliers
(None) no início do DropDownList.
Figura 10: o Categories
e Suppliers
DropDownLists incluem uma opção (Nenhum) (Clique para exibir a imagem em tamanho real)
Para salvar a opção (Nenhum) como um valor de banco de dados NULL
, precisamos retornar ao UpdateCommand
manipulador de eventos. Altere as categoryIDValue
variáveis e supplierIDValue
para que sejam inteiros anuláveis e atribua a elas um valor diferente Nothing
apenas se dropDownList s SelectedValue
não for uma cadeia de caracteres vazia:
int? categoryIDValue = null;
if (!string.IsNullOrEmpty(categories.SelectedValue))
categoryIDValue = Convert.ToInt32(categories.SelectedValue);
int? supplierIDValue = null;
if (!string.IsNullOrEmpty(suppliers.SelectedValue))
supplierIDValue = Convert.ToInt32(suppliers.SelectedValue);
Com essa alteração, um valor de Nothing
será passado para o UpdateProduct
método BLL se o usuário tiver selecionado a opção (Nenhum) de 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 à sintaxe DataList; EditItemTemplate
use a sintaxe de associação de dados para atribuir os valores de campo de dados correspondentes com as propriedades de controle da Web apropriadas; e, no UpdateCommand
manipulador de 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 diferentes controles da Web, certifique-se de manipular corretamente os valores do banco de dados NULL
. Ao considerar NULL
s, é imperativo que você não apenas exiba corretamente um valor existente NULL
na interface de edição, mas também que você ofereça um meio para marcar um valor como NULL
. Para DropDownLists em DataLists, isso normalmente significa adicionar um estático ListItem
cuja Value
propriedade é definida explicitamente 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 ou não selecionado.
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 Dennis Patterson, David Suru e Randy Schmidt. Interessado em revisar meus próximos artigos do MSDN? Nesse caso, deixe-me uma linha em mitchell@4GuysFromRolla.com.
Comentários
https://aka.ms/ContentUserFeedback.
Brevemente: Ao longo de 2024, vamos descontinuar progressivamente o GitHub Issues como mecanismo de feedback para conteúdos e substituí-lo por um novo sistema de feedback. Para obter mais informações, veja:Submeter e ver comentários