Repeater dentro de Repeater (DataList dentro de DataList ou GridView dentro de GridView)

Imagine a seguinte situação: você tem uma lista de um determinado objeto e cada objeto dessa lista tem uma propriedade. Essa propriedade é uma lista de um determinado objeto e você precisa popular um Repeater.

Vamos dar nomes aos objetos: suponha que você tenha uma lista de professores e cada professor tem seus alunos, bem, alguns irão dizer que é fácil, cada vez que o Repeater fizer um ItemDataBound basta fazer um busca novamente no banco de dados e listar o resultado. Como sempre me deparo com essa situação e vira e mexe algum me pergunta se essa é a melhor maneira de fazer resolvi escrever um artigo.

É muito simples, se a sua coleção já vem populada, basta você passar essa lista de objetos para o outro controle dentro do seu Repater (nesse caso outro Repeater), e isso será feito a cada ItemDataBound.

Classes

Temos as seguintes classes:

/// <summary> /// Classe mãe /// </summary> public abstract class Pessoa { private string _nome = string.Empty; public string Nome { get { return _nome; } set { _nome = value; } } public Pessoa() { } } /// <summary> /// Professor implementa Pessoa /// </summary> public class Professor : Pessoa { private string _materia = string.Empty; public string Materia { get { return _materia; } set { _materia = value; } } /// <summary> /// Um professor tem uma lista de alunos /// </summary> private System.Collections.Generic.List<Aluno> alunos = new System.Collections.Generic.List<Aluno>(); public System.Collections.Generic.List<Aluno> Alunos { get { return alunos; } set { alunos = value; } } public Professor(string nome, string materia, System.Collections.Generic.List<Aluno> alunos) { Nome = nome; Materia = materia; Alunos = alunos; } } /// <summary> /// Aluno implementa Pessoa /// </summary> public class Aluno : Pessoa { private string _turma = string.Empty; public string Turma { get { return _turma; } set { _turma = value; } } public Aluno(string nome, string turma) { Nome = nome; Turma = turma; } }

WebForm

Agora que já conhecemos nossas classes vamos para a implementação disso em uma página. Primeiro vamos criar um Repeater na página e, dentro dele, criaremos um segundo repeater, como no exemplo abaixo:

<asp:Repeater ID="ProfessorRepeater" runat="server" OnItemDataBound="ProfessorRepeater_ItemDataBound"> <ItemTemplate> Professor: <%# Eval("Nome") %> <br /> Matéria: <%# Eval("Materia") %> <br /> Alunos: <asp:Repeater ID="AlunoRepeater" runat="server"> <HeaderTemplate> <table> <tr style="font-weight: bold"> <td> Nome</td> <td> Curso</td> </tr> </HeaderTemplate> <FooterTemplate> </table> </FooterTemplate> <ItemTemplate> <tr style="background-color: Gray"> <td> <%# Eval("Nome") %> </td> <td> <%# Eval("Turma")%> </td> </tr> </ItemTemplate> <AlternatingItemTemplate> <tr style="background-color: Silver"> <td> <%# Eval("Nome") %> </td> <td> <%# Eval("Turma") %> </td> </tr> </AlternatingItemTemplate> </asp:Repeater> </ItemTemplate> <SeparatorTemplate> <hr /> </SeparatorTemplate> </asp:Repeater>

Atente para o detalhe que o repeater AlunoRepater está escrevendo as propriedades Nome (que vem de Pessoa) e turma (que é da classe Aluno).

Bom, mas isso não irá funcionar dessa maneira. Vejamos no code behind da página como é a implementação disso.

Code Behind

No PageLoad os objetos são criados e populados.

protected void Page_Load(object sender, EventArgs e) { Page.Title = "Repeater dentro de Repeater (DataList dentro de DataLista ou GridView dentro de GridView)"; // lista de alunos que será atribuída aos professores List<Aluno> alunosEpaminondas = new List<Aluno>(); alunosEpaminondas.Add(new Aluno("Alan", "Sistemas da Informação")); alunosEpaminondas.Add(new Aluno("Fabio", "Ciência da Computação")); alunosEpaminondas.Add(new Aluno("Marcelo", "Desenvolvimento de Sistemas Web")); // Só para não falar que os professores tem os mesmos alunos List<Aluno> alunosAdolfo = new List<Aluno>(); alunosAdolfo.Clear(); alunosAdolfo.Add(new Aluno("Carol", "Análise de Sistemas")); alunosAdolfo.Add(new Aluno("Bruno", "Banco de Dados")); // lista de professores List<Professor> professores = new List<Professor>(); professores.Add(new Professor("Epaminondas", "Gestão de Projetos", alunosEpaminondas)); professores.Add(new Professor("Adolfo", "Programação Orientação a Objetos", alunosAdolfo)); ProfessorRepeater.DataSource = professores; // define o DataSource do repeater como a lista de objetos professores ProfessorRepeater.DataBind(); }

No controle ProfessorRepeater, no evento ItemDataBound que o controle AlunoRepeater é populado, veja como é simples fazer a conversão do item do repeater que é passado.

protected void ProfessorRepeater_ItemDataBound(object sender, RepeaterItemEventArgs e) { // verifica se o item é do tipo ItemType ou AlternatingItem, se não for retorna e não continua o processamento if (e.Item.ItemType != ListItemType.Item && e.Item.ItemType != ListItemType.AlternatingItem) return; // verifica se o objeto AlunoRepeater existe dentro do item if (e.Item.Controls.Contains((Repeater)e.Item.FindControl("AlunoRepeater"))) { // cria um objeto Repeater e define-o como o objeto AlunoRepeater do item Repeater alunoRepeater = (Repeater)e.Item.FindControl("AlunoRepeater"); // converte o item (linha do repeater) para um professor e define a propriedade Alunos como DataSource do repeater alunoRepeater.DataSource = ((Professor)e.Item.DataItem).Alunos; alunoRepeater.DataBind(); } }

Super simples e tranqüilo, não há segredos nisso. A grande sacada é não ter que conectar ao banco novamente apenas obter os outros objetos. É possível utilizar isso também na criação de menus, para exibir a notas fiscais e seus itens, pedidos e seus itens etc. Aí vai depender da necessidade de cada projeto.

Até a próxima!

Anúncios

Uma resposta para “Repeater dentro de Repeater (DataList dentro de DataList ou GridView dentro de GridView)

  1. Nice post. I study something like this here at UC Davis.
    It’s definitely helpful to learn new facts from fellow writers and gather ideas from new sources. I’d love to utilize some of this material on my own webpage (if you don’t mind). And of course, I’ll put
    up a backlink to your site at wordpress.com on my own blog.
    Kudos for posting.

    Curtir

Deixe um comentário

Preencha os seus dados abaixo ou clique em um ícone para log in:

Logotipo do WordPress.com

Você está comentando utilizando sua conta WordPress.com. Sair /  Alterar )

Foto do Google+

Você está comentando utilizando sua conta Google+. Sair /  Alterar )

Imagem do Twitter

Você está comentando utilizando sua conta Twitter. Sair /  Alterar )

Foto do Facebook

Você está comentando utilizando sua conta Facebook. Sair /  Alterar )

Conectando a %s