Nota
O acesso a esta página requer autorização. Pode tentar iniciar sessão ou alterar os diretórios.
O acesso a esta página requer autorização. Pode tentar alterar os diretórios.
por Scott Mitchell
Neste tutorial, mostraremos exemplos de como formatamos a aparência dos controles DataList e Repeater, usando funções de formatação em 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, como Font, ForeColor, BackColor, e BorderWidth, para citar algumas. O controle Repeater não contém nenhuma propriedade relacionada ao estilo. Qualquer configuração de estilo deve ser feita diretamente no código dos templates do Repetidor.
Muitas vezes, porém, a forma como os dados devem ser formatados depende dos próprios dados. Por exemplo, ao listar produtos, podemos querer exibir as informações do produto em uma cor de fonte cinza claro se ela for descontinuada, ou podemos destacar o UnitsInStock valor se for zero. Como vimos em tutoriais anteriores, o GridView, o DetailsView e o 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 foram vinculados a cada item (para o GridView foi oRowDataBoundevento; para o DataList e Repeater é oItemDataBoundevento). Nesse manipulador de eventos, os dados recém-vinculados podem ser examinados e as decisões de formatação tomadas. Examinamos essa técnica no tutorial Formatação personalizada com base em dados . - Funções de formatação 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, à Business Logic Layer ou a qualquer outra biblioteca de classes acessível a partir do aplicativo Web. Esta 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, mostraremos exemplos usando ambas as técnicas para ambos os controles.
Usando oItemDataBoundmanipulador de eventos
Quando os dados são vinculados a um DataList, seja a partir de um controle de fonte de dados ou através da atribuição programática de dados à propriedade do controle DataSource e chamando o seu método DataBind(), o evento DataBinding do DataList é acionado, a fonte de dados é enumerada e cada registro de dados é vinculado ao DataList. Para cada registro na fonte de dados, o DataList cria um DataListItem objeto que é vinculado ao registro atual. Durante esse processo, o DataList gera dois eventos:
-
ItemCreatedincêndios após a criação doDataListItem -
ItemDataBoundaciona após o registo atual ter sido vinculado aoDataListItem
As etapas a seguir descrevem o processo de vinculação de dados para o controle DataList.
O evento DataList s
DataBindingé acionadoOs dados estão vinculados à DataList
Para cada registo na fonte de dados
- Criar um
DataListItemobjeto - Acionar o
ItemCreatedevento - Vincular o registro ao
DataListItem - Acionar o
ItemDataBoundevento - Adicionar
DataListItemà coleçãoItems
- Criar um
Ao vincular dados ao controle Repeater, ele progride através da mesma sequência exata de etapas. A única diferença é que, em vez de DataListItem instâncias sendo criadas, o repetidor usa RepeaterItems.
Observação
O leitor astuto pode ter notado uma pequena anomalia entre a sequência de etapas que ocorrem quando o DataList e o Repeater estão vinculados a dados versus quando o GridView está vinculado a dados. Na extremidade final do processo de vinculação de dados, o GridView gera o DataBound evento, no entanto, nem o controle DataList nem o Repeater têm tal evento. Isso ocorre porque os controles DataList e Repeater foram criados no período de ASP.NET 1.x, antes que o padrão de manipulador de eventos de pré e pós-nível se tornasse comum.
Como com o 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 vinculados ao DataListItem ou RepeaterItem e afetaria a formatação do controle conforme necessário.
Para o controlo DataList, as alterações de formatação para o item inteiro podem ser implementadas usando as propriedades relacionadas ao estilo DataListItem, que incluem o padrão Font, ForeColor, BackColor, CssClass, e assim por diante. Para afetar a formatação de determinados controles da Web dentro do modelo DataList, precisamos acessar e modificar programaticamente o estilo desses controles da Web. Vimos como fazer isso novamente no tutorial Formatação personalizada com base em dados . 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 manipulador de ItemDataBound eventos devem ser feitas acessando e atualizando programaticamente os controles da Web dentro do modelo.
Como a técnica de ItemDataBound formatação para DataList e Repeater é praticamente idêntica, o nosso exemplo se concentrará no uso do DataList.
Etapa 1: Exibindo informações do produto na DataList
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 uma DataList que ItemTemplate exibia o nome, categoria, fornecedor, quantidade por unidade e preço de cada produto. Vamos repetir essa funcionalidade aqui neste tutorial. Para fazer isso, você pode recriar o DataList e seu ObjectDataSource do zero, ou você pode copiar sobre esses controles da página criada no tutorial anterior (Basics.aspx) e colá-los na página para este tutorial (Formatting.aspx).
Depois de replicar a funcionalidade DataList e ObjectDataSource de Basics.aspx para Formatting.aspx, reserve um momento para alterar a propriedade do DataList de ID para um nome mais descritivo DataList1. Em seguida, exiba a DataList em um navegador. Como mostra a Figura 1, a única diferença de formatação entre cada produto é que a cor de fundo alterna.
Figura 1: Os produtos estão listados no controle DataList (Clique para exibir a imagem em tamanho real)
Para este tutorial, vamos formatar a DataList de modo que qualquer produto com um preço inferior a $20.00 terá seu nome e preço unitário destacados em amarelo.
Etapa 2: Determinando programaticamente o valor dos dados no manipulador de eventos ItemDataBound
Uma vez que apenas os produtos com um preço inferior a $20.00 terão a formatação personalizada aplicada, devemos ser capazes de determinar o preço de cada produto. Ao vincular dados a uma DataList, a DataList enumera os registros em sua fonte de dados e, para cada registro, cria uma DataListItem instância, vinculando o registro da fonte de dados ao DataListItem. Depois que os dados do registro específico forem vinculados ao objeto atual DataListItem, o evento do DataList é acionado. Podemos criar um manipulador de eventos para esse evento para inspecionar os valores de dados para o 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 void ItemDataBoundFormattingExample_ItemDataBound
(object sender, DataListItemEventArgs e)
{
if (e.Item.ItemType == ListItemType.Item ||
e.Item.ItemType == ListItemType.AlternatingItem)
{
// Programmatically reference the ProductsRow instance bound
// to this DataListItem
Northwind.ProductsRow product =
(Northwind.ProductsRow)((System.Data.DataRowView)e.Item.DataItem).Row;
// See if the UnitPrice is not NULL and less than $20.00
if (!product.IsUnitPriceNull() && product.UnitPrice < 20)
{
// TODO: Highlight the product's name and price
}
}
}
Embora o conceito e a semântica por trás do manipulador de eventos DataList sejam ItemDataBound os mesmos usados pelo manipulador de eventos GridView RowDataBound no tutorial Formatação personalizada com base em dados , a sintaxe difere ligeiramente. Quando o ItemDataBound evento é acionado, o DataListItem recém-ligado aos dados é passado para o manipulador de eventos correspondente via e.Item (em vez de e.Row, como acontece com o manipulador de eventos do GridView RowDataBound). O manipulador de eventos DataList é ItemDataBound acionado para cada linha adicionada à DataList, incluindo linhas de cabeçalho, linhas de rodapé e linhas separadoras. No entanto, as informações do produto são vinculadas apenas às linhas de dados. Portanto, ao usar o ItemDataBound evento para inspecionar os dados vinculados à 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 seguintes oito valores:
AlternatingItemEditItemFooterHeaderItemPagerSelectedItemSeparator
Tanto Item como AlternatingItem``DataListItem compõem os itens de dados da DataList. Supondo que estamos a trabalhar com um Item ou um AlternatingItem, acessamos a instância real ProductsRow que estava vinculada ao atual DataListItem. A DataListItem propriedade DataItem contém uma referência ao DataRowView objeto, cuja Row propriedade fornece uma referência ao objeto real ProductsRow.
Em seguida, verificamos a ProductsRow propriedade da UnitPrice instância. Como o campo UnitPrice da tabela Produtos permite NULL valores, antes de tentarmos aceder à propriedade UnitPrice, devemos primeiro verificar se tem um valor NULL utilizando o método IsUnitPriceNull(). Se o valor UnitPrice não for NULL, verificamos se é inferior a 20,00 $. Se for realmente abaixo de US $ 20,00, então precisamos aplicar a formatação personalizada.
Etapa 3: Destacando o nome e o preço do produto
Uma vez que sabemos que o preço de um produto é inferior a US $ 20,00, tudo o que resta é destacar seu nome e preço. Para fazer isso, devemos primeiro referenciar programaticamente os controles Label no ItemTemplate que exibe o nome e o preço do produto. Em seguida, precisamos que eles exibam um fundo amarelo. Essas informações de formatação podem ser aplicadas modificando diretamente as propriedades de Labels 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 estilo que fornece a formatação desejada definida no , que foi criada e discutida no tutorial Styles.css em - AffordablePriceEmphasisdados.
Para aplicar a formatação, basta definir as propriedades dos dois controlos Web Label CssClass como AffordablePriceEmphasis, 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
Label ProductNameLabel = (Label)e.Item.FindControl("ProductNameLabel");
Label UnitPriceLabel = (Label)e.Item.FindControl("UnitPriceLabel");
// Next, set their CssClass properties
if (ProductNameLabel != null)
ProductNameLabel.CssClass = "AffordablePriceEmphasis";
if (UnitPriceLabel != null)
UnitPriceLabel.CssClass = "AffordablePriceEmphasis";
Com o manipulador de ItemDataBound eventos concluído, revisite a Formatting.aspx página num navegador. Como ilustra a Figura 2, os produtos com um preço inferior a $20,00 têm o seu nome e preço destacados.
Figura 2: Os produtos com menos de US$ 20,00 estão realçados (Clique para visualizar a imagem em tamanho real)
Observação
Como o DataList é renderizado 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 destacar o item inteiro amarelo quando seu preço fosse inferior a US$ 20,00, poderíamos ter substituído o código que fazia referência aos Rótulos e definir suas CssClass propriedades com a seguinte linha de código: e.Item.CssClass = "AffordablePriceEmphasis" (veja a Figura 3).
Os RepeaterItem s que compõem o controle Repeater, no entanto, não oferecem tais propriedades de nível de estilo. Portanto, a aplicação de formatação personalizada ao Repeater requer a aplicação de propriedades de estilo aos controles da Web dentro dos modelos do Repeater, assim como fizemos na Figura 2.
Figura 3: Todo o item do produto está realçado para produtos abaixo de US$ 20,00 (Clique para visualizar 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 dentro de um GridView TemplateField para aplicar formatação personalizada com base nos dados vinculados às linhas do GridView. Uma função de formatação é um método que pode ser invocado a partir 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, deixe 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 inferior a $20.00 (como fizemos no exemplo do ItemDataBound manipulador de eventos); se o preço for $20.00 ou superior, não exibamos o preço real, mas sim o texto, Por favor, ligue para obter uma cotaçã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, por favor, ligue para uma cotação de preço (Clique para ver 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 exiba o nome do produto junto com o texto [DESCONTINUADO], se necessário, e outra que exiba um preço destacado se for inferior a US$ 20,00, ou o texto, Por favor, peça 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 a partir da parte da sintaxe declarativa da página ASP.NET. O código para esses dois métodos segue:
protected string DisplayProductNameAndDiscontinuedStatus
(string productName, bool discontinued)
{
// Return just the productName if discontinued is false
if (!discontinued)
return productName;
else
// otherwise, return the productName appended with the text "[DISCONTINUED]"
return string.Concat(productName, " [DISCONTINUED]");
}
protected string DisplayPrice(Northwind.ProductsRow product)
{
// If price is less than $20.00, return the price, highlighted
if (!product.IsUnitPriceNull() && product.UnitPrice < 20)
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>";
}
Observe que o método DisplayProductNameAndDiscontinuedStatus aceita os valores dos campos de dados productName e discontinued como valores escalares, enquanto o método DisplayPrice aceita uma instância ProductsRow (em vez de um valor escalar unitPrice). Qualquer uma das abordagens funcionará; no entanto, se a função de formatação estiver a trabalhar com valores escalares que podem conter valores de base de dados NULL (como UnitPrice, mas nem ProductName nem Discontinued permitem valores NULL), deve-se ter cuidado especial ao lidar com estas entradas escalares.
Em particular, o parâmetro de entrada deve ser do tipo Object , uma vez que 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 string DisplayPrice(object unitPrice)
{
// If price is less than $20.00, return the price, highlighted
if (!Convert.IsDBNull(unitPrice) && ((decimal) unitPrice) < 20)
return string.Concat("<span class=\"AffordablePriceEmphasis\">",
((decimal) unitPrice).ToString("C"), "</span>");
else
// Otherwise return the text, "Please call for a price quote"
return "<span>Please call for a price quote</span>";
}
Observe que o unitPrice parâmetro de entrada é do tipo Object e que a instrução condicional foi modificada para verificar se unitPrice é 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 DataList s ItemTemplate
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 a partir 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 vinculação de dados:
<%# MethodName(inputParameter1, inputParameter2, ...) %>
No DataList ItemTemplate o ProductNameLabel controle Web Label atualmente exibe o nome do(s) produto(s) atribuindo à sua propriedade Text o resultado de <%# Eval("ProductName") %>. Para que ele exiba o nome mais o texto [DISCONTINUED], se necessário, atualize a sintaxe declarativa para que, em vez disso, atribua à Text propriedade o valor do DisplayProductNameAndDiscontinuedStatus método. Ao fazer isso, devemos passar o nome do produto e 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âmetros de entrada esperados, assim:
<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 do UnitPriceLabel Label para o valor retornado pelo Text método, assim como fizemos para exibir o nome do produto e o texto [DESCONTINUADO]. No entanto, em vez de passar o UnitPrice como um parâmetro de entrada escalar, passamos toda a instância 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 em vigor, reserve um momento para ver o nosso progresso num 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, por favor, peça uma cotação de preço (Clique para ver 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 à medida que cada registro na fonte de dados é vinculado 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 próprio item inteiro.
Alternativamente, a formatação personalizada pode ser realizada através de funções de formatação. Uma função de formatação é um método que pode ser invocado a partir dos modelos DataList ou Repeater que retorna o HTML a ser emitido em seu lugar. Muitas vezes, o HTML retornado por uma função de formatação é determinado pelos valores que estão sendo vinculados ao item atual. Esses valores podem ser passados para a função de formatação, como valores escalares ou passando o objeto inteiro que está sendo vinculado ao item (como a ProductsRow instância).
Feliz Programação!
Sobre o Autor
Scott Mitchell, autor de sete livros sobre ASP/ASP.NET e fundador da 4GuysFromRolla.com, trabalha com tecnologias Web da Microsoft desde 1998. Scott trabalha como consultor, formador e escritor independente. Seu último livro é Sams Teach Yourself ASP.NET 2.0 in 24 Hours. Ele pode ser contatado em mitchell@4GuysFromRolla.com.
Um agradecimento especial 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 rever meus próximos artigos do MSDN? Se for o caso, envie-me uma mensagem para mitchell@4GuysFromRolla.com.