How to nest repeaters in asp.net

◇◆丶佛笑我妖孽 提交于 2019-12-05 06:05:07

On the outer control, use the ItemDataBound event, like this:

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

Then, in the code-behind, handle the rptDiscipline_ItemDataBound event and manually bind the inner repeater. The repeater's ItemDataBound event fires once for each item that is repeated. So you'll do something like this:

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

EDIT: Updated to match your question's update.

You need to bind the outer repeater to a data source that has only one record per item you want the repeater to render. That means the data source needs to be a collection/list/datatable/etc that has only the disciplines in it. In your case, I would recommend getting a List<string> of disciplines from the DataTable for the inner collection, and bind the outer repeater to that. Then, the inner repeater binds to a subset of the data in the DataTable, using the ItemDataBound event. To get the subset, filter the DataTable through a DataView.

Here's code:

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

If you don't want to do it on the ItemDataBound event, you can also do it inline in your page by binding to a child property of the parent item if the child property is a collection like so:

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

First you need two lists, the list of disciplines, and then the list of all your data.

Data bind the list of disciplines to the outer repeater. If there are 6 disciplines, the repeater should repeat 6 times.

    <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();
}
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!