2011-05-30 76 views
7

我需要知道如何在用戶控件中嵌套中繼器。事情的html方面很好,它是我需要幫助的綁定和代碼。我只能找到使用sql數據源的例子,這並沒有什麼幫助。如何在asp.net中嵌套中繼器

我的中繼器看起來像這樣:

<asp:Panel ID="pnlDiscipline" runat="server" CssClass=""> 
    <asp:Repeater ID="rptDiscipline" runat="server"> 
     <ItemTemplate> 
      <h4><%#Eval("Discipline")%></h4> 
      <ul> 
       <asp:Repeater ID="rptPrograms" runat="server"> 
        <ItemTemplate> 
         <li><asp:HyperLink runat="server" Text='<%#Eval("Name") %>' NavigateUrl='<%#Eval("Link") %>'></asp:HyperLink> <%#Eval ("Notation") %></li> 
        </ItemTemplate> 
       </asp:Repeater> 
      </ul> 
     </ItemTemplate> 
    </asp:Repeater> 

我需要做的是希望合理明確的 - H4學科應出現一次,全部屬於該學科的條目列出如下,然後是下一個h4,然後是相應的列表,下一個h4等等。

數據源是在codebehind中創建的dataview,其中每一行都有'Name','Link','NOtation'和'Discipline'。我將dataview綁定到最外層的repeater,並且它的行爲如預期的那樣 - 列出每個條目的學科名稱,但表示在內部Repeater沒有數據

如何去使這項工作

編輯:?只是爲了澄清,我在代碼隱藏一個數據表中的每一行。在這個表中是一個項目,每個項目屬於一個學科,我想使用外部中繼器列出學科,內部列出每個學科下分組的項目,像這樣:

<h4>DISCIPLINE 1</h4> 
    <ul> 
     <li>Item</li> 
     <li>Item</li> 
     <li>Item</li> 
    </ul> 
<h4>DISCIPLINE 2</h4> 
    <ul>   
     <li>Item</li>    
     <li>Item</li> 
    </ul> 
<h4>DISCIPLINE 3</h4> 
    <ul>   
     <li>Item</li>    
     <li>Item</li> 
    </ul> 

目前,結合數據表到外中繼器給出了這樣的(例如使用上面的數據):

<h4>DISCIPLINE 1</h4> 
    <h4>DISCIPLINE 1</h4> 
    <h4>DISCIPLINE 1</h4> 
    <h4>DISCIPLINE 2</h4> 
    <h4>DISCIPLINE 2</h4> 
    <h4>DISCIPLINE 3</h4> 
    <h4>DISCIPLINE 3</h4> 

我用OnItemDataBound在外中繼器的建議,並且作爲一個測試用例我能夠訪問數據:

protected void rptDiscipline_ItemDataBound(Object Sender, RepeaterItemEventArgs e) 
{ 
    DataRowView drView = (DataRowView) e.Item.DataItem; 
    string name = drView["Name"] as string; 
    string link = drView["Link"] as string; 
    string notation = drView["Notation"] as string; 
    Response.Write(name + link + notation + "<br />") 
} 

所以數據是存在的,這正是我希望看到的,我只是不能把它綁定到內轉發。如果有更高性能的方法來實現這一點,我很樂意重做我的解決方案。

+0

你可以從這個線程http://stackoverflow.com/questions/1220715/creating-a-nested-repeater-control-dynamically/1220836#1220836 – 2011-05-30 03:59:07

+0

什麼是你想綁定到內得到的想法中繼?也許發佈你綁定到外部中繼器的類。 – EdmundYeung99 2011-05-30 04:00:14

+0

@Edmund - 編輯我的問題,希望能夠澄清我的問題 – Nathan 2011-05-30 04:30:09

回答

7

在外部控制,使用ItemDataBound事件,像這樣:

<asp:Repeater ID="rptDiscipline" runat="server" 
    OnItemDataBound="rptDiscipline_ItemDataBound"> 
... 

然後,在代碼隱藏,處理rptDiscipline_ItemDataBound事件和手動綁定內中繼器。對於每個重複的項目,中繼器的ItemDataBound事件觸發一次。所以,你會做這樣的事情:

protected void rptDiscipline_ItemDataBound(Object Sender, RepeaterItemEventArgs e) 
{ 
    // To get your data item, cast e.Item.DataItem to 
    // whatever you're using for the data object; for example a DataRow. 

    // Get the inner repeater: 
    Repeater rptPrograms = (Repeater) e.Item.FindControl("rptPrograms"); 

    // Set the inner repeater's datasource to whatever it needs to be. 
    rptPrograms.DataSource = ... 
    rptPrograms.DataMember = ... 
    rptPrograms.DataBind(); 
} 

編輯:更新,以符合您的問題的更新。

您需要將外部中繼器綁定到每個您希望中繼器呈現的項目只有一條記錄的數據源。這意味着數據源需要是一個集合/列表/數據表/等,只有其中的紀律。在你的情況下,我會建議從DataTable的內部集合中獲得一個List<string>規則,並將外部中繼器綁定到該集合。然後,內部中繼器使用ItemDataBound事件綁定到DataTable中的數據子集。要獲取子集,請通過DataView過濾DataTable。

這裏是代碼:

protected void Page_Load(object sender, EventItems e) 
{ 
    // get your data table 
    DataTable table = ... 

    if (!IsPostBack) 
    { 
     // get a distinct list of disciplines 
     List<string> disciplines = new List<string>(); 
     foreach (DataRow row in table) 
     { 
      string discipline = (string) row["Discipline"]; 
      if (!disciplines.Contains(discipline)) 
       disciplines.Add(discipline); 
     } 
     disciplines.Sort(); 

     // Bind the outer repeater 
     rptDiscipline.DataSource = disciplines; 
     rptDiscipline.DataBind(); 
    } 
} 

protected void rptDiscipline_ItemDataBound(Object Sender, RepeaterItemEventArgs e) 
{ 
    // To get your data item, cast e.Item.DataItem to 
    // whatever you're using for the data object 
    string discipline = (string) e.Item.DataItem; 

    // Get the inner repeater: 
    Repeater rptPrograms = (Repeater) e.Item.FindControl("rptPrograms"); 

    // Create a filtered view of the data that shows only 
    // the disciplines needed for this row 
    // table is the datatable that was originally bound to the outer repeater 
    DataView dv = new DataView(table); 
    dv.RowFilter = String.Format("Discipline = '{0}'", discipline); 

    // Set the inner repeater's datasource to whatever it needs to be. 
    rptPrograms.DataSource = dv; 
    rptPrograms.DataBind(); 
} 
+1

可以通過在內部中繼器上設置DataSource來完成嗎? – Nathan 2011-05-30 03:06:30

+0

嗨@charlie - 我明白你的意思,但不能得到它的工作。你能詳細說明你的答案嗎? – Nathan 2011-05-30 03:48:27

+0

@Nathan - 是的,可以看到@ lomaxx的回答 – Venemo 2011-05-30 09:41:23

4

如果你不想做的ItemDataBound事件,你也可以做它內嵌在你的頁面通過結合如果孩子的父項的子屬性屬性是這樣一個集合:

<asp:Repeater runat="server" ID="OuterRepeater" > 
    <ItemTemplate> 
     Outer Content: <%# DataBinder.Eval(Container.DataItem, "ParentProperty")%> 
     <asp:Repeater runat="server" ID="InnerRepeater" DataSource='<%# DataBinder.Eval(Container.DataItem, "ChildCollection")%>' > 
      <ItemTemplate> 
       <%# DataBinder.Eval(Container.DataItem, "ChildProperty")%> 
      </ItemTemplate> 
     </asp:Repeater> 
    </ItemTemplate> 
</asp:Repeater> 
1

首先,你需要兩個列表,學科列表,然後是所有數據的列表。

數據將規則列表綁定到外部中繼器。如果有6個學科,那麼中繼器應該重複6次。

<asp:Repeater ID="rptDiscipline" runat="server" OnItemDataBound="rptDiscipline_ItemDataBound"> 
     <ItemTemplate> 
      <h4><%# Eval("Discipline")%></h4> 
      <ul> 
       <asp:Repeater runat="server" ID="InnerRepeater" > 
        <ItemTemplate> 
         <li> 
          <asp:Label runat="server" ID="lbl" /> 
         </li> 
        </ItemTemplate> 
       </asp:Repeater> 
      </ul> 
     </ItemTemplate> 
    </asp:Repeater> 

protected void rptDiscipline_ItemDataBound(Object Sender, RepeaterItemEventArgs e) 
{  

    Repeater inner= (Repeater) e.Item.FindControl("InnerRepeater"); 

    //You want to bind all the data related to this discipline 
    DataRowView drView = (DataRowView) e.Item.DataItem; 
    string discipline= drView["Discipline"] as string; 

    //filter your total data with ones that match the discipline 

    inner.DataSource = //data bind the filtered list here 
    inner.DataBind(); 
} 
+0

我並不擔心我是如何實現它 - 認爲嵌套將是一個解決方案,如果不是這樣我就可以。你的例子不會產生我追逐的輸出 - 我需要一個按名稱分組的名稱列表 - 數據表中有150行,每行都有一個唯一的名稱和六個學科之一。 – Nathan 2011-05-30 04:57:27

+0

我想我現在明白你的問題了......我發佈了一些psudo代碼 – EdmundYeung99 2011-05-30 05:17:50