Introduction
This article describes how to use nested Repeater controls to display hierarchical data. You can apply this concept to other list-bound controls. This article only shows you
how to implement nested Repeaters and will not attempt to explain Repeaters in general.
Example
I am going to demonstrate a simple ASP.NET web application that will display a
questionnaire using nested Repeaters. In this example the first Repeater
will display the sections of the questionnaire and the second Repeater will display the
subsections and the third one will display questions. We have set two templates
for questions: Descriptive and Yes/No questions, the template will change dynamically according to the question type.
Using the code
NestedRepeater.aspx
<asp:Repeater ID="rptrParent" runat="server" OnItemDataBound="rptrParent_ItemDataBound">
<ItemTemplate>
<div style="padding: 10px 0px 10px 0px;">
<asp:Label ID="Label5" CssClass="label" Font-Bold="true" Font-Size="13pt" runat="server"
Text='<%#Eval("SectionName") %>'></asp:Label>
<asp:HiddenField ID="hdnSecID" runat="server" Value='<%#Eval("SectionID") %>' />
</div>
<div style="border: 1px solid black;">
<asp:Repeater ID="rptrQuestionnaire" runat="server">
<ItemTemplate>
<div style="padding-top: 10px; padding-left: 10px; float:left; width:70%;">
<asp:Label ID="Label6" CssClass="label" Font-Bold="true" Font-Size="12pt" runat="server"
Text='<%#Eval("SectionName") %>'></asp:Label>
<asp:HiddenField ID="hdnSubID" runat="server" Value='<%#Eval("SectionID") %>' />
</div>
<div style="float:right; width:30%;">
<asp:Label ID="Label8" CssClass="label" Font-Bold="true"
Font-Size="12pt" runat="server" Text="Standard"></asp:Label>
</div>
<div>
<asp:Repeater ID="rptrQuestionS" OnItemDataBound="rptrQuestionS_ItemDataBound" runat="server">
<ItemTemplate>
<asp:HiddenField ID="hdnQstnType" runat="server" Value='<%#Eval("QuestionType") %>' />
<div id="dvDesc" style="padding: 10px 0px 10px 0px;" runat="server">
<table style="width:100%;">
<tr>
<td style="width: 35px;" valign="top" >
<div style="border: 1px solid black; width: 25px;">
<asp:Label ID="lblQstNo" runat="server" Text=""></asp:Label>
</div>
</td>
<td style="width:65%;">
<asp:Label ID="Label1" CssClass="label" Font-Size="12pt"
runat="server" Text='<%#Eval("Question") %>'></asp:Label>
</td>
<td>
<asp:Label ID="Label7" runat="server" Text='<%#Eval("ISOStandardName") %>' ></asp:Label>
</td>
</tr>
<tr>
<td>
<asp:TextBox ID="TextBox1" TextMode="MultiLine"
Width="600px" Height="150px" runat="server"></asp:TextBox>
</td>
</tr>
</table>
</div>
<div id="dvYN" style="padding: 10px 0px 10px 0px;" runat="server">
<table style="width:100%;">
<tr>
<td style="width: 35px;" valign="top" >
<div style="border: 1px solid black; width: 25px;">
<asp:Label ID="lblQstNo1" runat="server" Text=""> </asp:Label>
</div>
</td>
<td style="width:65%;">
<asp:Label ID="Label2" CssClass="label" Font-Size="12pt"
runat="server" Text='<%#Eval("Question") %>'></asp:Label>
</td>
<td>
<asp:Label ID="Label9" runat="server"
Text='<%#Eval("ISOStandardName") %>' ></asp:Label>
</td>
</tr>
<tr>
<td>
<asp:RadioButtonList CssClass="label" ID="RadioButtonList1" runat="server">
<asp:ListItem Value="1">Yes</asp:ListItem>
<asp:ListItem Value="0">No</asp:ListItem>
</asp:RadioButtonList>
</td>
</tr>
</table>
</div>
</ItemTemplate>
</asp:Repeater>
</div>
</ItemTemplate>
</asp:Repeater>
</div>
</ItemTemplate>
</asp:Repeater>
NestedRepeater.aspx.cs
In the BindQuestionnaire
method the sections of the questionnaire will bind to
the first Repeater
and in the ItemDataBound
event of the
first Repeater
, the sub sections
and questions will bind to the second and third Repeater
s. On the questions
ItemDataBound
event the templates of the questions will change dynamically according to the
question type.
private void BindQuestionnaire()
{
CQuestionnaire objQst = new CQuestionnaire();
List<AQuestionnaire> objList = new List<AQuestionnaire>();
objQst.QID = 14;
objList = objQst.SelectQSections();
rptrParent.DataSource = objList;
rptrParent.DataBind();
}
protected void rptrParent_ItemDataBound(object sender, RepeaterItemEventArgs e)
{
CQuestionnaire objQst = new CQuestionnaire();
HiddenField hdnSec = e.Item.FindControl("hdnSecID") as HiddenField;
Repeater rpChild = e.Item.FindControl("rptrQuestionnaire") as Repeater;
rpChild.DataSource = objQst.SelectQSubSections(Convert.ToInt32(hdnSec.Value));
rpChild.DataBind();
foreach (RepeaterItem repeaterItem in rpChild.Items)
{
CQuestionnaire objQst1 = new CQuestionnaire();
string sSubID = ((HiddenField)(repeaterItem.FindControl("hdnSubID"))).Value;
((Repeater)(repeaterItem.FindControl("rptrQuestionS"))).DataSource =
objQst1.SelectQstns(Convert.ToInt32(sSubID));
((Repeater)(repeaterItem.FindControl("rptrQuestionS"))).DataBind();
}
}
protected void rptrQuestionS_ItemDataBound(object sender, RepeaterItemEventArgs e)
{
CQuestionnaire objQst = new CQuestionnaire();
HiddenField hdnQstnTyp = e.Item.FindControl("hdnQstnType") as HiddenField;
Label lblQstNo = e.Item.FindControl("lblQstNo") as Label;
Label lblQstNo1 = e.Item.FindControl("lblQstNo1") as Label;
HtmlGenericControl dvDS = (HtmlGenericControl)e.Item.FindControl("dvDesc");
HtmlGenericControl dvYN = (HtmlGenericControl)e.Item.FindControl("dvYN");
if (hdnQstnTyp.Value.ToString() == "1")
{
dvYN.Visible = true;
dvDS.Visible = false;
lblQstNo1.Text = (e.Item.ItemIndex + 1).ToString();
}
else
{
dvYN.Visible = false;
dvDS.Visible = true;
lblQstNo.Text = (e.Item.ItemIndex + 1).ToString();
}
}