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, analisaremos exemplos de como formatamos a aparência dos controles DataList e Repeater, usando funções de formatação dentro de modelos ou manipulando o evento DataBound.
Introdução
Como vimos no tutorial anterior, o DataList oferece várias propriedades relacionadas ao estilo que afetam sua aparência. Em particular, vimos como atribuir classes CSS padrão às propriedades do DataList HeaderStyle, ItemStyle, AlternatingItemStyle e SelectedItemStyle. Além dessas quatro propriedades, o DataList inclui várias outras propriedades relacionadas ao estilo, comoFont, , ForeColorBackColore BorderWidth, para citar algumas. O controle Repeater não contém nenhuma propriedade relacionada ao estilo. Essas configurações de estilo devem ser feitas diretamente dentro das marcações nos modelos do Repeater.
Muitas vezes, porém, a forma como os dados devem ser formatados depende dos próprios dados. Por exemplo, ao listar produtos, talvez queiramos exibir as informações do produto em uma cor de fonte cinza claro se ela for descontinuada, ou talvez queiramos realçar o UnitsInStock valor se for zero. Como vimos em tutoriais anteriores, GridView, DetailsView e FormView oferecem duas maneiras distintas de formatar sua aparência com base em seus dados:
-
O
DataBoundevento cria um manipulador de eventos para o evento apropriadoDataBound, que é acionado depois que os dados são associados a cada item (para o GridView foi oRowDataBoundevento; para DataList e Repeater é oItemDataBoundevento). Nesse manipulador de eventos, os dados associados podem ser examinados e as decisões de formatação tomadas. Examinamos essa técnica no tutorial Formatação Personalizada Baseada em Dados . - Formatando funções em modelos ao usar TemplateFields nos controles DetailsView ou GridView ou um modelo no controle FormView, podemos adicionar uma função de formatação à classe code-behind da página ASP.NET, à Camada de Lógica Empresarial ou a qualquer outra biblioteca de classes acessível do aplicativo Web. Essa função de formatação pode aceitar um número arbitrário de parâmetros de entrada, mas deve retornar o HTML para renderizar no modelo. As funções de formatação foram examinadas pela primeira vez no tutorial Usando TemplateFields no controle GridView .
Ambas as técnicas de formatação estão disponíveis com os controles DataList e Repeater. Neste tutorial, analisaremos exemplos usando ambas as técnicas para ambos os controles.
Usando oItemDataBoundmanipulador de eventos
Quando os dados são associados a um DataList, seja de um controle de fonte de dados ou por meio da atribuição programática de dados à propriedade do controle e chamada do seu método DataSource, o evento DataBind() do DataList é acionado, a fonte de dados é enumerada e cada registro de dados é associado ao DataList. Para cada registro na fonte de dados, a Lista de Dados cria um DataListItem objeto associado ao registro atual. Durante esse processo, a Lista de Dados gera dois eventos:
-
ItemCreatedé acionado após a criação deDataListItem -
ItemDataBoundé acionado após o registro atual ter sido associado aoDataListItem
As etapas a seguir descrevem o processo de associação de dados para o controle DataList.
O evento do DataList é acionado
Os dados estão associados à Lista de Dados
Para cada registro na fonte de dados
- Criar um objeto
DataListItem - Acionar o
ItemCreatedevento - Vincular o registro ao
DataListItem - Acionar o
ItemDataBoundevento - Adicionar
DataListItemà coleçãoItems
- Criar um objeto
Ao associar dados ao controle Repetidor, ele progride exatamente pela mesma sequência de etapas. A única diferença é que, em vez de instâncias DataListItem serem criadas, o Repetidor usa RepeaterItems.
Observação
O leitor astuto pode ter notado uma pequena anomalia entre a sequência de etapas que ocorre quando o DataList e o Repetidor estão associados a dados em comparação com quando o GridView está associado aos dados. No final do processo de associação de dados, o GridView aciona o DataBound evento; no entanto, nem o controle DataList nem Repeater têm tal evento. Isso ocorre porque os controles DataList e Repeater foram criados na época do ASP.NET 1.x, antes que o padrão de manipulador de eventos antes e depois do nível se tornasse comum.
Assim como no GridView, uma opção para formatação com base nos dados é criar um manipulador de eventos para o ItemDataBound evento. Esse manipulador de eventos inspecionaria os dados que tinham acabado de ser associados ao DataListItem ou RepeaterItem e afetariam a formatação do controle, conforme necessário.
Para o controle DataList, as alterações de formatação para todo o item podem ser implementadas usando as DataListItem propriedades relacionadas ao estilo s, que incluem o padrão Font, ForeColor, BackColor, CssClass e assim por diante. Para afetar a formatação de controles Web específicos no modelo do DataList, precisamos acessar e modificar programaticamente o estilo desses controles Web. Vimos como fazer isso de volta no tutorial formatação personalizada baseada em dados . Assim como o controle Repeater, a RepeaterItem classe não tem propriedades relacionadas ao estilo; portanto, todas as alterações relacionadas ao estilo feitas em um RepeaterItem no manipulador de eventos ItemDataBound devem ser realizadas acessando e atualizando programaticamente controles Web dentro do modelo.
Como a ItemDataBound técnica de formatação para DataList e Repeater é praticamente idêntica, nosso exemplo se concentrará em usar a Lista de Dados.
Etapa 1: Exibindo informações do produto na Lista de Dados
Antes de nos preocuparmos com a formatação, vamos primeiro criar uma página que usa uma DataList para exibir informações do produto. No tutorial anterior , criamos um DataList cujo ItemTemplate nome, categoria, fornecedor, quantidade por unidade e preço de cada produto foi exibido. Vamos repetir essa funcionalidade aqui neste tutorial. Para fazer isso, você pode recriar o DataList e seu ObjectDataSource do zero ou copiar esses controles da página criada no tutorial anterior (Basics.aspx) e cole-os na página deste tutorial (Formatting.aspx).
Depois de replicar a funcionalidade DataList e ObjectDataSource de Basics.aspx dentro de Formatting.aspx, reserve um momento para alterar a propriedade ID do DataList de DataList1 para uma descrição mais descritiva ItemDataBoundFormattingExample. Em seguida, exiba a Lista de Dados em um navegador. Como mostra a Figura 1, a única diferença de formatação entre cada produto é que a cor da tela de fundo se alterna.
Figura 1: Os produtos são listados no controle DataList (clique para exibir a imagem em tamanho real)
Para este tutorial, vamos formatar a Lista de Dados de modo que todos os produtos com um preço inferior a US$ 20,00 tenham o nome e o preço unitário realçados em amarelo.
Etapa 2: Determinando programaticamente o valor dos dados no manipulador de eventos ItemDataBound
Como somente os produtos com um preço abaixo de US$ 20,00 terão a formatação personalizada aplicada, devemos ser capazes de determinar o preço de cada produto. Ao associar dados a um DataList, a Lista de Dados enumera os registros em sua fonte de dados e, para cada registro, cria uma DataListItem instância, associando o registro da fonte de dados ao DataListItem. Depois que os dados do registro específico tiverem sido associados ao objeto atual DataListItem , o evento DataList ItemDataBound será acionado. Podemos criar um manipulador de eventos para esse evento para inspecionar os valores de dados do atual DataListItem e, com base nesses valores, fazer as alterações de formatação necessárias.
Crie um ItemDataBound evento para o DataList e adicione o seguinte código:
Protected Sub ItemDataBoundFormattingExample_ItemDataBound _
(sender As Object, e As DataListItemEventArgs) _
Handles ItemDataBoundFormattingExample.ItemDataBound
If e.Item.ItemType = ListItemType.Item OrElse _
e.Item.ItemType = ListItemType.AlternatingItem Then
' Programmatically reference the ProductsRow instance
' bound to this DataListItem
Dim product As Northwind.ProductsRow = _
CType(CType(e.Item.DataItem, System.Data.DataRowView).Row, _
Northwind.ProductsRow)
' See if the UnitPrice is not NULL and less than $20.00
If Not product.IsUnitPriceNull() AndAlso product.UnitPrice < 20 Then
' TODO: Highlight the product's name and price
End If
End If
End Sub
Embora o conceito e a semântica por trás do manipulador de eventos DataList ItemDataBound sejam os mesmos usados pelo manipulador de eventos do RowDataBound GridView no tutorial Formatação Personalizada Baseada em Dados , a sintaxe é ligeiramente diferente. Quando o ItemDataBound evento é acionado, o DataListItem recém-ligado aos dados é passado para o manipulador de eventos correspondente por meio do e.Item (em vez do e.Row, como acontece com o manipulador de eventos do RowDataBound GridView). O manipulador de eventos DataList ItemDataBound é acionado para cada linha adicionada ao DataList, incluindo linhas de cabeçalho, linhas de rodapé e linhas separadora. No entanto, as informações do produto são associadas apenas às linhas de dados. Portanto, ao usar o ItemDataBound evento para inspecionar os dados associados ao DataList, precisamos primeiro garantir que estamos trabalhando com um item de dados. Isso pode ser feito verificando a DataListItem propriedade sItemType, que pode ter um dos oito valores a seguir:
AlternatingItemEditItemFooterHeaderItemPagerSelectedItemSeparator
Ambos Item e AlternatingItem``DataListItem compõem os itens de dados do DataList. Supondo que estamos trabalhando com um Item ou AlternatingItem, acessamos a instância real ProductsRow associada ao atual DataListItem. A propriedade DataListItemDataItem s contém uma referência ao objeto DataRowView, cuja propriedade Row fornece uma referência ao objeto real ProductsRow.
Em seguida, verificamos a propriedade ProductsRow da instância UnitPrice. Como o campo da UnitPrice tabela Produtos permite NULL valores, antes de tentar acessar a UnitPrice propriedade, primeiro devemos verificar se ela tem um NULL valor usando o IsUnitPriceNull() método. Se o valor do UnitPrice não for NULL, verificamos se ele é menor que US$ 20,00. Se, de fato, estiver abaixo de US$ 20,00, precisaremos aplicar a formatação personalizada.
Etapa 3: Realçando o nome e o preço do produto
Depois de sabermos que o preço de um produto é menor que US$ 20,00, tudo o que resta é realçar seu nome e preço. Para fazer isso, primeiro devemos referenciar programaticamente os controles Label no ItemTemplate que exibem o nome e o preço do produto. Em seguida, precisamos que eles exibam um plano de fundo amarelo. Essas informações de formatação podem ser aplicadas modificando diretamente as propriedades de Rótulos BackColor (LabelID.BackColor = Color.Yellow); idealmente, porém, todas as questões relacionadas à exibição devem ser expressas por meio de folhas de estilo em cascata. Na verdade, já temos uma folha de estilos que fornece a formatação desejada, definida em Styles.css - AffordablePriceEmphasis, que foi criada e discutida no tutorial Formatação Personalizada Baseada em Dados.
Para aplicar a formatação, basta definir as duas propriedades dos controles da Web do rótulo como CssClass, conforme mostrado no código a seguir.
' Highlight the product name and unit price Labels
' First, get a reference to the two Label Web controls
Dim ProductNameLabel As Label = CType(e.Item.FindControl("ProductNameLabel"), Label)
Dim UnitPriceLabel As Label = CType(e.Item.FindControl("UnitPriceLabel"), Label)
' Next, set their CssClass properties
If ProductNameLabel IsNot Nothing Then
ProductNameLabel.CssClass = "AffordablePriceEmphasis"
End If
If UnitPriceLabel IsNot Nothing Then
UnitPriceLabel.CssClass = "AffordablePriceEmphasis"
End If
Após concluir o ItemDataBound manipulador de eventos, volte para a página Formatting.aspx em um navegador. Como ilustra a Figura 2, esses produtos com um preço abaixo de US$ 20,00 têm seu nome e preço realçados.
Figura 2: Esses produtos com menos de US$ 20,00 são realçados (clique para exibir a imagem em tamanho real)
Observação
Como a Lista de Dados é renderizada como um HTML <table>, suas DataListItem instâncias têm propriedades relacionadas ao estilo que podem ser definidas para aplicar um estilo específico ao item inteiro. Por exemplo, se quiséssemos realçar o item inteiro amarelo quando seu preço fosse menor que US$ 20,00, poderíamos ter substituído o código que fazia referência aos Rótulos e definido suas CssClass propriedades pela seguinte linha de código: e.Item.CssClass = "AffordablePriceEmphasis" (consulte a Figura 3).
As RepeaterItem s que compõem o controle Repeater, no entanto, não oferecem propriedades de estilo de nível semelhante. Portanto, a aplicação de formatação personalizada ao Repetidor requer a aplicação de propriedades de estilo aos controles Web nos modelos do Repetidor, assim como fizemos na Figura 2.
Figura 3: O item inteiro do produto é realçado para produtos abaixo de US$ 20,00 (clique para exibir a imagem em tamanho real)
Usando funções de formatação de dentro do modelo
No tutorial Usando TemplateFields no controle GridView , vimos como usar uma função de formatação em um GridView TemplateField para aplicar a formatação personalizada com base nos dados associados às linhas do GridView. Uma função de formatação é um método que pode ser invocado de um modelo e retorna o HTML a ser emitido em seu lugar. As funções de formatação podem residir na classe code-behind da página ASP.NET ou podem ser centralizadas em arquivos de classe na App_Code pasta ou em um projeto separado da Biblioteca de Classes. Mover a função de formatação para fora da classe code-behind da página ASP.NET é ideal se você planeja usar a mesma função de formatação em várias páginas ASP.NET ou em outros aplicativos Web ASP.NET.
Para demonstrar as funções de formatação, vamos fazer com que as informações do produto incluam o texto [DESCONTINUADO] ao lado do nome do produto se ele for descontinuado. Além disso, vamos destacar o preço em amarelo se for menor que US$ 20,00 (como fizemos no exemplo do manipulador de eventos ItemDataBound); se o preço for US$ 20,00 ou superior, não vamos exibir o preço real, mas sim o texto: "Por favor, ligue para obter uma cotação de preço." A Figura 4 mostra uma captura de tela da listagem de produtos com essas regras de formatação aplicadas.
Figura 4: Para produtos caros, o preço é substituído pelo texto, chame uma cotação de preço (Clique para exibir a imagem em tamanho real)
Etapa 1: Criar as funções de formatação
Para este exemplo, precisamos de duas funções de formatação: uma que exibe o nome do produto junto com o texto [DESCONTINUADO], se necessário, e outra que exibe um preço destacado, se for menor que US$ 20,00, ou o texto "Por favor, entre em contato para obter uma cotação de preço" caso contrário. Vamos criar essas funções na classe code-behind da página ASP.NET e nomeá-las DisplayProductNameAndDiscontinuedStatus e DisplayPrice. Ambos os métodos precisam retornar o HTML para renderizar como uma cadeia de caracteres e ambos precisam ser marcados Protected (ou Public) para serem invocados da parte de sintaxe declarativa da página ASP.NET. O código para esses dois métodos segue:
Protected Function DisplayProductNameAndDiscontinuedStatus _
(productName As String, discontinued As Boolean) As String
' Return just the productName if discontinued is false
If Not discontinued Then
Return productName
Else
' otherwise, return the productName appended with the text "[DISCONTINUED]"
Return String.Concat(productName, " [DISCONTINUED]")
End If
End Function
Protected Function DisplayPrice(product As Northwind.ProductsRow) As String
' If price is less than $20.00, return the price, highlighted
If Not product.IsUnitPriceNull() AndAlso product.UnitPrice < 20 Then
Return String.Concat("<span class="AffordablePriceEmphasis">", _
product.UnitPrice.ToString("C"), "</span>")
Else
' Otherwise return the text, "Please call for a price quote"
Return "<span>Please call for a price quote</span>"
End If
End Function
Observe que o DisplayProductNameAndDiscontinuedStatus método aceita os valores dos productName campos de dados e discontinued como valores escalares, enquanto o DisplayPrice método aceita uma ProductsRow instância (em vez de um unitPrice valor escalar). Qualquer abordagem funcionará; no entanto, se a função de formatação estiver lidando com valores escalares que podem conter valores de banco de dados NULL (como UnitPrice; nem ProductName nem Discontinued permitem valores de NULL), deve-se tomar cuidado especial no tratamento dessas entradas escalares.
Em particular, o parâmetro de entrada deve ser do tipo Object , pois o valor de entrada pode ser uma DBNull instância em vez do tipo de dados esperado. Além disso, uma verificação deve ser feita para determinar se o valor de entrada é ou não um valor de banco de dados NULL . Ou seja, se quiséssemos que o DisplayPrice método aceitasse o preço como um valor escalar, teríamos que usar o seguinte código:
Protected Function DisplayPrice(ByVal unitPrice As Object) As String
' If price is less than $20.00, return the price, highlighted
If Not Convert.IsDBNull(unitPrice) AndAlso CType(unitPrice, Decimal) < 20 Then
Return String.Concat("<span class="AffordablePriceEmphasis">", _
CType(unitPrice, Decimal).ToString("C"), "</span>")
Else
' Otherwise return the text, "Please call for a price quote"
Return "<span>Please call for a price quote</span>"
End If
End Function
Observe que o unitPrice parâmetro de entrada é do tipo Object e que a instrução condicional foi modificada para verificar se unitPrice está DBNull ou não. Além disso, como o unitPrice parâmetro de entrada é passado como um Object, ele deve ser convertido em um valor decimal.
Etapa 2: Chamando a função de formatação do ItemTemplate da Lista de Dados
Com as funções de formatação adicionadas à nossa classe code-behind da página ASP.NET, tudo o que resta é invocar essas funções de formatação do DataList s ItemTemplate. Para chamar uma função de formatação de um modelo, coloque a chamada de função dentro da sintaxe de associação de dados:
<%# MethodName(inputParameter1, inputParameter2, ...) %>
No DataList ItemTemplate, o controle Web Label ProductNameLabel atualmente exibe o nome do produto atribuindo à sua propriedade Text o resultado de <%# Eval("ProductName") %>. Para exibir o nome junto com o texto [DESCONTINUADO], se necessário, atualize a sintaxe declarativa para que atribua à propriedade Text o valor do método DisplayProductNameAndDiscontinuedStatus. Ao fazer isso, devemos passar o nome do produto e os valores descontinuados usando a Eval("columnName") sintaxe.
Eval retorna um valor de tipo Object, mas o DisplayProductNameAndDiscontinuedStatus método espera parâmetros de entrada do tipo String e Boolean; portanto, devemos converter os valores retornados pelo Eval método para os tipos de parâmetro de entrada esperados, da seguinte maneira:
<h4>
<asp:Label ID="ProductNameLabel" runat="server"
Text='<%# DisplayProductNameAndDiscontinuedStatus((string) Eval("ProductName"),
(bool) Eval("Discontinued")) %>'>
</asp:Label>
</h4>
Para exibir o preço, podemos simplesmente definir a propriedade UnitPriceLabel Label Text para o valor retornado pelo método DisplayPrice, assim como fizemos para exibir o nome do produto e o texto [DESCONTINUADO]. No entanto, em vez de passar como UnitPrice um parâmetro de entrada escalar, passamos a instância inteira ProductsRow :
<asp:Label ID="UnitPriceLabel" runat="server"
Text='<%# DisplayPrice((Northwind.ProductsRow)
((System.Data.DataRowView) Container.DataItem).Row) %>'>
</asp:Label>
Com as chamadas para as funções de formatação implementadas, veja o progresso em um navegador. Sua tela deve ser semelhante à Figura 5, com os produtos descontinuados incluindo o texto [DESCONTINUADO], e os produtos que custam mais de US$ 20,00 tendo seu preço substituído pelo texto Por favor, ligue para uma cotação de preço.
Figura 5: Para produtos caros, o preço é substituído pelo texto, chame uma cotação de preço (clique para exibir a imagem em tamanho real)
Resumo
A formatação do conteúdo de um controle DataList ou Repeater com base nos dados pode ser realizada usando duas técnicas. A primeira técnica é criar um manipulador de eventos para o ItemDataBound evento, que é acionado conforme cada registro na fonte de dados está associado a um novo DataListItem ou RepeaterItem.
ItemDataBound No manipulador de eventos, os dados do item atual podem ser examinados e, em seguida, a formatação pode ser aplicada ao conteúdo do modelo ou, para DataListItem s, ao item inteiro em si.
Como alternativa, a formatação personalizada pode ser realizada por meio de funções de formatação. Uma função de formatação é um método que pode ser invocado nos modelos DataList ou Repeater que retorna o HTML para ser emitido em seu lugar. Muitas vezes, o HTML retornado por uma função de formatação é determinado pelos valores associados ao item atual. Esses valores podem ser passados para a função de formatação, como valores escalares ou passando todo o objeto que está sendo associado ao item (como a ProductsRow instância).
Divirta-se programando!
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 independente, treinador e escritor. 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 Yaakov Ellis, Randy Schmidt e Liz Shulok. Interessado em revisar meus próximos artigos do MSDN? Se assim for, deixe-me uma linha em mitchell@4GuysFromRolla.com.