Uso de TemplateFields no controle DetailsView (C#)
por Scott Mitchell
Os mesmos recursos TemplateFields disponíveis com o GridView também estão disponíveis com o controle DetailsView. Neste tutorial, exibiremos um produto por vez usando um DetailsView contendo TemplateFields.
Introdução
O TemplateField oferece um grau mais alto de flexibilidade na renderização de dados do que os controles BoundField, CheckBoxField, HyperLinkField e outros campos de dados. No tutorial anterior , examinamos o uso do TemplateField em um GridView para:
- Exibir vários valores de campo de dados em uma coluna. Especificamente, os
FirstName
campos eLastName
foram combinados em uma coluna GridView. - Use um controle Web alternativo para expressar um valor de campo de dados. Vimos como mostrar o
HiredDate
valor usando um controle Calendar. - Mostrar status informações com base nos dados subjacentes. Embora a
Employees
tabela não contenha uma coluna que retorna o número de dias em que um funcionário esteve no trabalho, pudemos exibir essas informações no exemplo GridView no tutorial anterior com o uso de um método TemplateField e formatação.
Os mesmos recursos TemplateFields disponíveis com o GridView também estão disponíveis com o controle DetailsView. Neste tutorial, exibiremos um produto por vez usando um DetailsView que contém dois TemplateFields. O primeiro TemplateField combinará os UnitPrice
campos de dados , UnitsInStock
e UnitsOnOrder
em uma linha DetailsView. O segundo TemplateField exibirá o valor do Discontinued
campo, mas usará um método de formatação para exibir "SIM" se Discontinued
for true
e "NÃO" caso contrário.
Figura 1: Dois TemplateFields são usados para personalizar a exibição (clique para exibir a imagem em tamanho real)
Vamos começar!
Etapa 1: Associar os dados ao DetailsView
Conforme discutido no tutorial anterior, ao trabalhar com TemplateFields, geralmente é mais fácil começar criando o controle DetailsView que contém apenas BoundFields e, em seguida, adicione novos TemplateFields ou converta os BoundFields existentes em TemplateFields conforme necessário. Portanto, inicie este tutorial adicionando um DetailsView à página por meio do Designer e associando-o a um ObjectDataSource que retorna a lista de produtos. Essas etapas criarão um DetailsView com BoundFields para cada um dos campos de valor não booliano do produto e um CheckBoxField para o único campo de valor booliano (Descontinuado).
Abra a DetailsViewTemplateField.aspx
página e arraste DetailsView da Caixa de Ferramentas para o Designer. Na marca inteligente do DetailsView, escolha adicionar um novo controle ObjectDataSource que invoca o ProductsBLL
método da GetProducts()
classe.
Figura 2: Adicionar um novo controle ObjectDataSource que invoca o GetProducts()
método (clique para exibir a imagem em tamanho real)
Para este relatório, SupplierID
remova , ProductID
, CategoryID
e ReorderLevel
BoundFields. Em seguida, reordene os BoundFields para que o CategoryName
e SupplierName
BoundFields apareçam imediatamente após o ProductName
BoundField. Fique à vontade para ajustar as HeaderText
propriedades e as propriedades de formatação para o BoundFields conforme você achar adequado. Assim como no GridView, essas edições no nível BoundField podem ser executadas por meio da caixa de diálogo Campos (acessível clicando no link Editar Campos na marca inteligente do DetailsView) ou por meio da sintaxe declarativa. Por fim, desmarque os valores de propriedade e Width
detailsView Height
para permitir que o controle DetailsView se expanda com base nos dados exibidos e marcar caixa de seleção Habilitar Paginação na marca inteligente.
Depois de fazer essas alterações, a marcação declarativa do controle DetailsView deve ser semelhante à seguinte:
<asp:DetailsView ID="DetailsView1" runat="server" AutoGenerateRows="False"
DataKeyNames="ProductID" DataSourceID="ObjectDataSource1" AllowPaging="True"
EnableViewState="False">
<Fields>
<asp:BoundField DataField="ProductName" HeaderText="Product"
SortExpression="ProductName" />
<asp:BoundField DataField="CategoryName" HeaderText="Category"
ReadOnly="True" SortExpression="CategoryName" />
<asp:BoundField DataField="SupplierName" HeaderText="Supplier"
ReadOnly="True" SortExpression="SupplierName" />
<asp:BoundField DataField="QuantityPerUnit"
HeaderText="Qty/Unit" SortExpression="QuantityPerUnit" />
<asp:BoundField DataField="UnitPrice" HeaderText="Price"
SortExpression="UnitPrice" />
<asp:BoundField DataField="UnitsInStock"
HeaderText="Units In Stock" SortExpression="UnitsInStock" />
<asp:BoundField DataField="UnitsOnOrder"
HeaderText="Units On Order" SortExpression="UnitsOnOrder" />
<asp:CheckBoxField DataField="Discontinued"
HeaderText="Discontinued" SortExpression="Discontinued" />
</Fields>
</asp:DetailsView>
Reserve um momento para exibir a página por meio de um navegador. Neste ponto, você deverá ver um único produto listado (Chai) com linhas mostrando o nome do produto, categoria, fornecedor, preço, unidades em estoque, unidades sob encomenda e seus status descontinuados.
Figura 3: Os detalhes do produto são mostrados usando uma série de BoundFields (clique para exibir a imagem em tamanho real)
Etapa 2: combinando o preço, as unidades em estoque e as unidades em ordem em uma linha
O DetailsView tem uma linha para os UnitPrice
campos , UnitsInStock
e UnitsOnOrder
. Podemos combinar esses campos de dados em uma única linha com um TemplateField adicionando um novo TemplateField ou convertendo um dos campos existentes UnitPrice
, UnitsInStock
e UnitsOnOrder
BoundFields em um TemplateField. Embora eu pessoalmente prefira converter BoundFields existentes, vamos praticar adicionando um novo TemplateField.
Comece clicando no link Editar Campos na marca inteligente DetailsView para abrir a caixa de diálogo Campos. Em seguida, adicione um novo TemplateField e defina sua HeaderText
propriedade como "Preço e Inventário" e mova o novo TemplateField para que ele seja posicionado acima do UnitPrice
BoundField.
Figura 4: Adicionar um Novo TemplateField ao controle DetailsView (clique para exibir a imagem em tamanho real)
Como esse novo TemplateField conterá os valores exibidos atualmente nos UnitPrice
campos , UnitsInStock
e UnitsOnOrder
BoundFields, vamos removê-los.
A última tarefa para esta etapa é definir a ItemTemplate
marcação para o Price and Inventory TemplateField, que pode ser realizado por meio da interface de edição de modelo do DetailsView no Designer ou manualmente por meio da sintaxe declarativa do controle. Assim como acontece com o GridView, a interface de edição de modelo do DetailsView pode ser acessada clicando no link Editar Modelos na marca inteligente. A partir daqui, você pode selecionar o modelo a ser editado na lista suspensa e, em seguida, adicionar todos os controles da Web da Caixa de Ferramentas.
Para este tutorial, comece adicionando um controle Label ao Price and Inventory TemplateField's ItemTemplate
. Em seguida, clique no link Editar DataBindings da marca inteligente do controle Web rótulo e associe a Text
propriedade ao UnitPrice
campo .
Figura 5: associar a propriedade do Text
rótulo ao UnitPrice
campo de dados (clique para exibir a imagem em tamanho real)
Formatar o Preço como um Conversor de Moedas
Com essa adição, o Controle Web rótulo Price e Inventory TemplateField agora exibirá apenas o preço do produto selecionado. A Figura 6 mostra uma captura de tela do nosso progresso até agora quando exibida por meio de um navegador.
Figura 6: o campo Preço e Inventário mostra o preço (clique para exibir a imagem em tamanho real)
Observe que o preço do produto não é formatado como uma moeda. Com um BoundField, a formatação é possível definindo a HtmlEncode
propriedade como false
e a DataFormatString
propriedade como {0:formatSpecifier}
. No entanto, para um TemplateField, todas as instruções de formatação devem ser especificadas na sintaxe de vinculação de dados ou por meio do uso de um método de formatação definido em algum lugar dentro do código do aplicativo (como na classe code-behind da página ASP.NET).
Para especificar a formatação para a sintaxe de vinculação de dados usada no controle Web Rótulo, retorne à caixa de diálogo DataBindings clicando no link Editar DataBindings da marca inteligente do Rótulo. Você pode digitar as instruções de formatação diretamente na lista suspensa Formatar ou selecionar uma das cadeias de caracteres de formato definidas. Assim como acontece com a propriedade BoundField DataFormatString
, a formatação é especificada usando {0:formatSpecifier}
.
Para o UnitPrice
campo, use a formatação de moeda especificada selecionando o valor de lista suspensa apropriado ou digitando {0:C}
manualmente.
Figura 7: formatar o preço como um Conversor de Moedas (Clique para exibir a imagem em tamanho real)
Declarativamente, a especificação de formatação é indicada como um segundo parâmetro nos Bind
métodos ou Eval
. As configurações feitas por meio do Designer resultam na seguinte expressão de vinculação de dados na marcação declarativa:
<asp:Label ID="Label1" runat="server" Text='<%# Eval("UnitPrice", "{0:C}") %>'/>
Adicionando os campos de dados restantes ao TemplateField
Neste ponto, exibimos e formatamos o UnitPrice
campo de dados no Price and Inventory TemplateField, mas ainda precisamos exibir os UnitsInStock
campos e UnitsOnOrder
. Vamos exibi-los em uma linha abaixo do preço e entre parênteses. Na interface de edição de modelo no Designer, essa marcação pode ser adicionada posicionando o cursor dentro do modelo e simplesmente digitando o texto a ser exibido. Como alternativa, essa marcação pode ser inserida diretamente na sintaxe declarativa.
Adicione a marcação estática, os controles da Web de rótulo e a sintaxe de vinculação de dados para que o Price e o Inventory TemplateField exibam as informações de preço e inventário da seguinte maneira:
UnitPrice
(Em Estoque/ Em Ordem:UnitsInStock / UnitsOnOrder)
Depois de executar essa tarefa, a marcação declarativa do DetailsView deve ser semelhante à seguinte:
<asp:DetailsView ID="DetailsView1" runat="server" AutoGenerateRows="False"
DataKeyNames="ProductID" DataSourceID="ObjectDataSource1" AllowPaging="True"
EnableViewState="False">
<Fields>
<asp:BoundField DataField="ProductName"
HeaderText="Product" SortExpression="ProductName" />
<asp:BoundField DataField="CategoryName" HeaderText="Category"
ReadOnly="True" SortExpression="CategoryName" />
<asp:BoundField DataField="SupplierName"
HeaderText="Supplier" ReadOnly="True"
SortExpression="SupplierName" />
<asp:BoundField DataField="QuantityPerUnit"
HeaderText="Qty/Unit" SortExpression="QuantityPerUnit" />
<asp:TemplateField HeaderText="Price and Inventory">
<ItemTemplate>
<asp:Label ID="Label1" runat="server"
Text='<%# Eval("UnitPrice", "{0:C}") %>'></asp:Label>
<br />
<strong>
(In Stock / On Order: </strong>
<asp:Label ID="Label2" runat="server"
Text='<%# Eval("UnitsInStock") %>'></asp:Label>
<strong>/</strong>
<asp:Label ID="Label3" runat="server"
Text='<%# Eval("UnitsOnOrder") %>'>
</asp:Label><strong>)</strong>
</ItemTemplate>
</asp:TemplateField>
<asp:CheckBoxField DataField="Discontinued"
HeaderText="Discontinued" SortExpression="Discontinued" />
</Fields>
</asp:DetailsView>
Com essas alterações, consolidamos as informações de preço e inventário em uma única linha DetailsView.
Figura 8: As informações de preço e inventário são exibidas em uma única linha (clique para exibir a imagem em tamanho real)
Etapa 3: Personalizando as informações de campo descontinuadas
A Products
coluna da Discontinued
tabela é um valor bit que indica se o produto foi descontinuado. Ao associar um DetailsView (ou GridView) a um controle de fonte de dados, os campos de valor booliano, como Discontinued
, são implementados como CheckBoxFields, enquanto campos de valor não boolianos, como ProductID
, ProductName
e assim por diante, são implementados como BoundFields. O CheckBoxField é renderizado como uma caixa de seleção desabilitada que é verificada se o valor do campo de dados é True e desmarcado de outra forma.
Em vez de exibir o CheckBoxField, talvez queiramos exibir texto indicando se o produto foi descontinuado ou não. Para fazer isso, podemos remover o CheckBoxField do DetailsView e, em seguida, adicionar um BoundField cuja DataField
propriedade foi definida como Discontinued
. Tire um momento para fazer isso. Após essa alteração, o DetailsView mostra o texto "True" para produtos descontinuados e "False" para produtos que ainda estão ativos.
Figura 9: As cadeias de caracteres True e False são usadas para exibir o estado descontinuado (clique para exibir a imagem em tamanho real)
Imagine que não queríamos que as cadeias de caracteres "True" ou "False" fossem usadas, mas "SIM" e "NÃO", em vez disso. Essa personalização pode ser executada com o auxílio de um TemplateField e um método de formatação. Um método de formatação pode receber qualquer número de parâmetros de entrada, mas deve retornar o HTML (como uma cadeia de caracteres) para injetar no modelo.
Adicione um método de formatação à DetailsViewTemplateField.aspx
classe code-behind da página chamada DisplayDiscontinuedAsYESorNO
que aceita um booliano como um parâmetro de entrada e retorna uma cadeia de caracteres. Conforme discutido no tutorial anterior, esse método deve ser marcado como protected
ou public
para ser acessível a partir do modelo.
protected string DisplayDiscontinuedAsYESorNO(bool discontinued)
{
if (discontinued)
return "YES";
else
return "NO";
}
Esse método verifica o parâmetro de entrada (discontinued
) e retorna "SIM" se for true
, caso contrário, "NÃO".
Observação
No método de formatação examinado no tutorial anterior, lembre-se de que estávamos passando um campo de dados que poderia conter NULL
s e, portanto, necessário para marcar se o valor da propriedade do HiredDate
funcionário tinha um valor de banco de dados NULL
antes de acessar a EmployeesRow
propriedade do HiredDate
. Esse marcar não é necessário aqui, pois a Discontinued
coluna nunca pode ter valores de banco de dados NULL
atribuídos. Além disso, é por isso que o método pode aceitar um parâmetro de entrada booliano em vez de ter que aceitar uma ProductsRow
instância ou um parâmetro do tipo object
.
Com esse método de formatação concluído, tudo o que resta é chamá-lo do TemplateField.ItemTemplate
Para criar o TemplateField, remova o Discontinued
BoundField e adicione um novo TemplateField ou converta o Discontinued
BoundField em um TemplateField. Em seguida, na exibição de marcação declarativa, edite o TemplateField para que ele contenha apenas um ItemTemplate que invoca o DisplayDiscontinuedAsYESorNO
método , passando o valor da propriedade da Discontinued
instância atualProductRow
. Isso pode ser acessado por meio do Eval
método . Especificamente, a marcação do TemplateField deve ser semelhante a:
<asp:TemplateField HeaderText="Discontinued" SortExpression="Discontinued">
<ItemTemplate>
<%# DisplayDiscontinuedAsYESorNO((bool)
Eval("Discontinued")) %>
</ItemTemplate>
</asp:TemplateField>
Isso fará com que o DisplayDiscontinuedAsYESorNO
método seja invocado ao renderizar o DetailsView, passando o ProductRow
valor da Discontinued
instância. Como o Eval
método retorna um valor do tipo object
, mas o DisplayDiscontinuedAsYESorNO
método espera um parâmetro de entrada do tipo bool
, convertemos o Eval
valor retornado dos métodos para bool
. Em DisplayDiscontinuedAsYESorNO
seguida, o método retornará "SIM" ou "NÃO", dependendo do valor recebido. O valor retornado é o que é exibido nesta linha DetailsView (consulte a Figura 10).
Figura 10: Os valores SIM ou NÃO agora são mostrados na linha descontinuada (clique para exibir a imagem em tamanho real)
Resumo
O TemplateField no controle DetailsView permite um maior grau de flexibilidade na exibição de dados do que o disponível com os outros controles de campo e é ideal para situações em que:
- Vários campos de dados precisam ser exibidos em uma coluna GridView
- Os dados são melhor expressos usando um controle da Web em vez de texto sem formatação
- A saída depende dos dados subjacentes, como exibir metadados ou reformatar os dados
Embora TemplateFields permita um maior grau de flexibilidade na renderização dos dados subjacentes do DetailsView, a saída detailsView ainda parece um pouco boxy, pois cada campo é renderizado como uma linha em um HTML <table>
.
O controle FormView oferece um maior grau de flexibilidade na configuração da saída renderizada. O FormView não contém campos, mas apenas uma série de modelos (ItemTemplate
, EditItemTemplate
, HeaderTemplate
e assim por diante). Veremos como usar o FormView para obter ainda mais controle do layout renderizado em nosso próximo tutorial.
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. O revisor principal deste tutorial foi Dan Jagers. 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