Search code examples
c#asp.netrepeaternested-repeater

Nested Repeaters in ASP.NET


I have a class that contains hierarchical data. I want to present this data in my ASP.net webapp using nested repeaters. How do I do this? I've only ever done one level of nesting, how do I do say five levels?

Each item can have zero or many sub items. I'm basically just indenting at each subleveling using some css stuff. I do not want to use the treeview control, I want to strictly stick with a repeater.

Update:
My data comes from a database. I have an item datatable with some basic properties.

Item
{
   ID,
   Name,
   Description,
   ...
}

Then I have a many to many table with:

Parent
{
   ParentID,
   ChildID
}

I'm iterating through each item and displaying its children; and its children's children. I assume this would best be accomplished with nested repeaters, but I could be wrong.


Solution

  • It's always cleaner to deal with the datasource than messing about with ItemDataBound, but this is even more the case when nesting Repeaters:

    <asp:Repeater DataSource="<%#ColOfCol%>" runat="server">
      <ItemTemplate>
        <tr>
          <asp:Repeater DataSource="<%#Container.DataItem%>" runat="server">
            <ItemTemplate>
              <td><%#SomeExtractingMethodLikeEval()%></td>
            </ItemTemplate>
          </asp:Repeater>
        </tr>
      </ItemTemplate>
    </asp:Repeater>
    

    The inner datasource could also be an evaluated property, or a call to a method that returns the enumeration wanted. Just be aware that it will be called with an object. I prefer to write the specific version, and then overload:

    protected IEnumerable<string> GetNames(Family fam)
    {
      foreach(Person p in fam.Members)
        yield return p.FirstName + " " + p.Surname;
    }
    protected IEnumerable<string> GetNames(object famObj)
    {
        return GetNames((Family)famObj);
    }
    

    One thing to be aware of is that if you want to get the current object in the parent repeater than you have to obtain it with:

    ((RepeaterItem)Container.Parent.Parent).DataItem