Nested Repeaters in ASP.NET

前端 未结 4 1318
攒了一身酷
攒了一身酷 2020-12-01 05:13

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

相关标签:
4条回答
  • 2020-12-01 05:46

    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
    
    0 讨论(0)
  • 2020-12-01 05:46

    I've found that the simplest way to do nested repeaters without worrying about databinding events is to just set the DataSource using <%# %> syntax.

    For example:

    <asp:Repeater runat="server" id="Departments">
      <ItemTemplate>
        Name: <%# Eval("DeptName") %>
        Employees:
        <asp:Repeater runat="server" DataSource='<%# Eval("Employees") %>'>
          <ItemTemplate><%# Eval("Name") %></ItemTemplate>
          <SeparatorTemplate>,</SeparatorTemplate>
        </asp:Repeater>
      </ItemTemplate>
    </asp:Repeater>
    

    This is presuming that your Departments class has an Employees property - eg:

    public class Department {
      public string DeptName {get; set;}
      public IEnumerable<Employee> Employees {get; set;}
    }
    public class Employee {
      public string Name {get; set;}
    }
    

    If your outer-repeater object doesn't have a property corresponding to the inner-repeater object you can still use this trick, by adding a method in your code-behind that does the calculation. So your inner repeater might become:

    <asp:Repeater runat="server" DataSource='<%# GetEmployees(Container.DataItem) %>'>
    

    and then GetEmployees might look something like:

    protected IEnumerable<Employee> GetEmployees(object item) {
      var dept = (Department) item;
      // then do whatever is necessary to get the employees from dept
      return employees;
    }
    
    0 讨论(0)
  • 2020-12-01 05:56
    <asp:Repeater ID="R1" runat="server">
        <ItemTemplate>
            <asp:Repeater ID="R2" runat="server">
            </asp:Repeater>
        </ItemTemplate>
    </asp:Repeater>
    
    
    R1.ItemDataBound += (s, e) =>
    {
        var r2 = e.Item.FindControl("R2") as Repeater;
        r2.DataSource = something;
        r2.DataBind();
    };
    

    Be aware that FindControl is not recursive, it will only get the children.

    0 讨论(0)
  • You can nest repeaters without a problem. More then 2 levels deep gets nasty though. Here's how:

    The html looks something like this:

    <asp:Repeater ID="r1" runat="server" OnItemDataBound="r1_ItemDataBound">
    <ItemTemplate>
    <!-- top level repeater element template here -->
        <asp:Repeater ID="r2" runat="server" onitemdatabound="r2_ItemDataBound">
        <ItemTemplate>
    <!-- child repeater element template here -->
        </ItemTemplate>
        </asp:Repeater>
    </ItemTemplate>
    </asp:Repeater>
    

    The codebehind looks like this:

        protected void r1_ItemDataBound(object sender, RepeaterItemEventArgs e) {
            Repeater r2 = (Repeater)e.Item.FindControl("r2");
            r2.DataSource = yourDataSourceHere; // you'll have to query for appropriate data
            r2.DataBind();
        }
    
        protected void r2_ItemDataBound(object sender, RepeaterItemEventArgs e) {
            // do the same thing here for the 3rd nested repeater if you have a third, and so on
        }
    
    0 讨论(0)
提交回复
热议问题