42

階層データを含むクラスがあります。ネストされたリピーターを使用して、このデータを ASP.net webapp に表示したいと考えています。どうすればいいですか?ネストを 1 レベルしか行ったことがないのですが、5 レベルとはどのように言えますか?

各アイテムには、ゼロまたは多数のサブアイテムを含めることができます。私は基本的に、いくつかのCSSを使用して各サブレベリングでインデントしています。ツリービュー コントロールは使いたくありません。厳密にリピーターを使用したいと考えています。

更新:
私のデータはデータベースから取得されます。いくつかの基本的なプロパティを持つアイテムのデータテーブルがあります。

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

次に、多対多のテーブルがあります:

Parent
{
   ParentID,
   ChildID
}

各アイテムを繰り返し処理し、その子を表示しています。とその子の子。これは、ネストされたリピーターで実現するのが最善だと思いますが、間違っている可能性があります。

4

4 に答える 4

83

データバインド イベントを気にせずにネストされたリピーターを実行する最も簡単な方法は、<%# %>構文を使用して DataSource を設定することです。

例えば:

<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>

これは、 Departments クラスに Employees プロパティがあることを前提としています-例:

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

外部リピーター オブジェクトに内部リピーター オブジェクトに対応するプロパティがない場合でも、コード ビハインドに計算を行うメソッドを追加することで、このトリックを使用できます。したがって、内部リピーターは次のようになります。

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

GetEmployees は次のようになります。

protected IEnumerable<Employee> GetEmployees(object item) {
  var dept = (Department) item;
  // then do whatever is necessary to get the employees from dept
  return employees;
}
于 2010-08-26T01:16:23.133 に答える
36

ItemDataBound をいじるよりもデータソースを処理する方が常にクリーンですが、これは Repeater をネストする場合にさらに当てはまります。

<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>

内部データソースは、評価されたプロパティ、または必要な列挙を返すメソッドの呼び出しでもあります。オブジェクトで呼び出されることに注意してください。特定のバージョンを記述してからオーバーロードすることを好みます。

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);
}

注意すべきことの 1 つは、親リピーターで現在のオブジェクトを取得する場合は、次の方法で取得する必要があるということです。

((RepeaterItem)Container.Parent.Parent).DataItem
于 2010-08-26T01:31:46.480 に答える
13

問題なくリピーターをネストできます。ただし、2 レベル以上の深さは厄介です。方法は次のとおりです。

html は次のようになります。

<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>

コードビハインドは次のようになります。

    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
    }
于 2010-08-26T01:06:09.917 に答える
2
<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();
};

FindControl再帰的ではないことに注意してください。子のみを取得します。

于 2010-08-26T01:06:47.347 に答える