.NET

27 mar, 2013

Trabalhando com Repeater no ASP.NET

Publicidade

Um dos mais importantes objetos para apresentação de dados no ASP.NET é o Repeater. A função do Repeater é mostrar uma coleção de dados compatíveis com as interfaces IEnumerable ou IListSource (dados de tabela de banco de dados, arquivo XML, lista de objetos,etc…) com poucas linhas de código e de maneira organizada.

O Repeater é dividido em cinco templates:

  • HeaderTemplate: Conteúdo do cabeçalho do Repeater (não obrigatório);
  • FooterTemplate: Conteúdo de rodapé do Repeater (não obrigatório);
  • ItemTemplate: Conteúdo que irá ser exibido em cada loop do Repeater;
  • AlternatingItemTemplate: Tem a mesma função do ItemTemplate, serve para diferenciar a exibição entre os loops (não obrigatório);
  • SeparatorTemplate: Conteúdo que irá ser exibido entre os loops (não obrigatório).

Principais propriedades

  • DataSource: Recebe a fonte de dados que o Repeater irá utilizar. Pode ser qualquer coleção que seja compatível com as interfaces IEnumerable ou IListSource, exemplos: consultas de banco de dados, dados de XML, lista de objetos, entre outras;
  • Items: Essa propriedade é para ler a fonte de dados do Repeater.

Principais métodos

  • DataBind(): Serve para que o Repeater renderize a fonte de dados informado na propriedade “DataSource” na página.

Principais eventos

  • ItemCommand: Disparado quando um botão que esta dentro do repeater é clicado;
  • ItemCreated: Disparado quando um item é criado pelo Repeater;
  • ItemDataBound: Disparado antes de o Repeater renderizar as informações na página.

Exemplo simples

Vamos criar uma lista do tipo string para usar como uma fonte de dados para um Repeater.

Default.aspx

<asp:Repeater ID="rptAnimais" runat="server">
 <ItemTemplate>
 <%# Container.DataItem %>
 </ItemTemplate>
</asp:Repeater>

Default.cs

 List<String> AnimaisLista = new List<String>();
 AnimaisLista.Add("Cachorro");
 AnimaisLista.Add("Gato");
 AnimaisLista.Add("Galinha");

 rptAnimais.DataSource = AnimaisLista ;
 rptAnimais.DataBind();

O resultado será:

repeater_1

Como você pode observar, ele gerou um laço de repetição passando por todos os itens da fonte de dados que foi informado. Cada item foi representado pelo código <%# Container.DataItem %>:

Em cada ciclo do Repeater vamos ter o objeto Container, contendo as principais propriedades:

  • ItemIndex: Índice dos ciclos do Repeater, começando do zero;
  • DataItem: O objeto do ciclo do repeater. Nesse caso como informamos um objeto List<String> como fonte de dados, o DataItem do ciclo foi o objeto String.

Exemplo avançado

Neste exemplo iremos utilizar uma lista de objetos para a exibição, o evento ItemDataBound e como utilizar um Repeater dentro de outro.

Para esse teste vamos utilizar as seguintes classes modelo:

namespace WebApplication
{
    public class Banda
    {
        public String Nome { get; set; }
        public List<Album> AlbumLista { get; set; }
    }

    public class Album
    {
        public String Titulo { get; set; }
        public DateTime Lancamento { get; set; }
        public String Comentario { get; set; }
    }
}

O detalhe nesse caso é que dentro do objeto Banda temos uma lista de objetos Album. Para exibir uma lista de bandas, irá ser necessário também exibir a lista de álbuns de cada banda também, para isso iremos utilizar um Repeater dentro de outro.

Default.cs

protected void Page_Load(object sender, EventArgs e)
{
    //A lista de objetos é preenchida por um método
    //que poderia vir de uma tabela do banco de dados
    // ou um xml, por exemplo.
    List<Banda> BandaLista = GetBandaLista();
 
    //Setamos a função "rptBanda_ItemDataBound" para escutar o evento "ItemDataBound".
    this.rptBanda.ItemDataBound += new RepeaterItemEventHandler(rptBanda_ItemDataBound);
 
    //Informamos a fonte de dados, e que o Repeater deve renderiza-la.
    this.rptBanda.DataSource = BandaLista;
    this.rptBanda.DataBind();
}

Default.aspx

<asp:Repeater ID="rptBand" runat="server">
    <HeaderTemplate>
        <table>
            <thead>
                <tr style="background-color:#aaaaaa;">
                    <th>Id</th>
                    <th>Name</th>
                    <th>Album Name</th>
                    <th>Release Date</th>
                    <th>Comment</th>
                </tr>
            </thead>
            <tbody>
    </HeaderTemplate>
    <ItemTemplate>
        <tr>
            <th><%# Container.ItemIndex + 1 %></th>
            <th><%# DataBinder.Eval(Container.DataItem,"Name") %></th>
            <th></th>
            <th></th>
            <th></th>
        </tr>
        <asp:Repeater ID="rptAlbum" runat="server">
            <ItemTemplate>
                <tr>
                    <th></th>
                    <th></th>
                    <th><%# DataBinder.Eval(Container.DataItem,"Title") %></th>
                    <th><%# ((WebApplication.Album)Container.DataItem).Release.ToShortDateString() %></th>
                    <th><%# String.IsNullOrEmpty((String)DataBinder.Eval(Container.DataItem, "Comment")) ? "No comment" : DataBinder.Eval(Container.DataItem, "Comment")%></th>
                </tr>
            </ItemTemplate>
            <AlternatingItemTemplate>
                <tr style="background-color:#cccccc;">
                    <th></th>
                    <th></th>
                    <th><%# DataBinder.Eval(Container.DataItem, "Title")%></th>
                    <th><%# ((WebApplication.Album)Container.DataItem).Release.ToShortDateString() %></th>
                    <th><%# String.IsNullOrEmpty((String)DataBinder.Eval(Container.DataItem, "Comment")) ? "No comment" : DataBinder.Eval(Container.DataItem, "Comment")%></th>
                </tr>
            </AlternatingItemTemplate>
        </asp:Repeater>
    </ItemTemplate>
    <FooterTemplate>
            </tbody>
            <tfoot >
                <tr>
                    <th>Band Table 2013</th>
                </tr>
            </tfoot>
        </table>
    </FooterTemplate>
</asp:Repeater>

O resultado será:

2 (3)

Primeiramente, devemos observar o uso dos templates HeaderTemplate e FooterTemplate. Como aprendemos, não é obrigatório utilizá-los, sendo assim, poderíamos ter colocado o conteúdo de início e fim da tabela fora do Repeater sem problemas. O diferencial do uso desses templates é, caso a fonte de dados não contenha nenhum item, o conteúdo do HeaderTemplate e FooterTemplate não será exibido na página.

Também estamos usando o template AlternatingItemTemplate para a lista de álbuns, que na maioria dos casos irá ser o mesmo conteúdo do ItemTemplate, apenas diferenciando as cores. Particularmente, eu prefiro utilizar apenas o ItemTemplate, diferenciando o estilo por css, segue o exemplo:

<tr <%# Container.ItemIndex % 2 != 0 ? "class=\"alternado\"" : "" %>></tr>

A condição Container.ItemIndex % 2 != 0 identifica se o ciclo possui um índice par ou ímpar, e aplica um estilo caso o ciclo for de índice par. Caso você não conheça, estou utilizando o operador ternário, para fazer a condição na mesma linha,  já que expressões de databinding <%# %> não suporta várias linhas de código. Caso o operador ternário não supre as suas necessidades, você deve utilizar o evento ItemDataBound para realizar suas operações, ou criar um evento específico e invocar dentro do operador como:

<%# MeuMetodo(DataBinder.Eval(Container.DataItem, "Title"))%>

No exemplo, você viu duas formas de imprimir o conteúdo de uma propriedade do objeto doloop:

1. Utilizando o método DataBinder.Eval(Container.DataItem, “NomeDaPropriedade”)

<%# DataBinder.Eval(Container.DataItem, "Title")%>

2. Fazendo um casting do objeto Container.DataItem

<%# ((WebApplication.Album)Container.DataItem).Release.ToShortDateString() %>

Conclusão

Com o Repeater evitamos usar os laços de repetição, como o for e o while, deixando assim o código de uma página *.aspx muito mais limpo. Com os eventos é possível ter controle total sobre o Repeater e com o que ele irá mostrar, tornando-o assim uma ferramenta muito útil e poderosa.