This article is basically an extension of my previous article. For those of you that have not seen my previous article, kindly have a look at the following link. It'll provide a basic idea of what a repeater control is all about.
http://www.c-sharpcorner.com/UploadFile/17e8f6/repeater-control-in-Asp-Net/
Toady in this article we are basically going to learn how to nest repeater controls within one another. The preceding link will help you with the basic concepts of what a repeater control is and which scenario is best for using a repeater control. Ok now without wasting my time and your time we will proceed to what and how to make use of a nested repeater control.
For instance let us say we are asked to create a report of a particular school student's Marksheet. Where the report will have a list of student data (such as their StudId, Rollno, Name etcetera) and below their Mark in the respective subject along with the total and their result, in other words whether they are ing or not. In such cases we could use a repeater control for displaying the report in a user specificed format.
From the preceding figure, you can see that we have a parent repeater control that is used for displaying the Student Releated Data (StudId, Name and RollNo) and an inner repeater control that is used for displaying the respective student Mark Details. In case of nested repeaters with a repeater control, you will encounter the problem that your nested control, in other words the inner repeater control, will not be accessbile to you directly in code behind. That is because it is placed inside the parent's repeater ItemTemplate. For accessing the inner repeater control you'll need to make use a RepeaterItem class that will help you to access the inner repeater control or any control that is placed inside the ItemTemplate or FooterTemplate or AlternatingItemTemplate class, by using the FindControl method of the RepeaterItem class.
The other thing that is interesting is that since the inner repeater control is also a Data Control, that means we will need to set its DataSource for displaying data within the inner repeater control. If you only set the Outer/Parent's DataSource property and you don't set the inner control's repeater control DataSource property then in only the parent repeater control data will be displayed and no data will be displayed in the child/inner control. As we discussed earlier, we can't directly access the inner repeater control directly in code behind. Then how to set its DataSource property? Well the answer is quite simply and logically since we know that we placed our inner repeater control inside the outer one's within the <ItemTemplate>. So we could always make use of the ItemDataBound event of the outer repeater control whereby we can find the inner Repetaer Control using the RepeaterItem class. The following snapshot shows that.
protected void Repeater1_ItemDataBound(object sender, RepeaterItemEventArgs e)
{
if (e.Item.ItemType == ListItemType.AlternatingItem || e.Item.ItemType == ListItemType.Item)
{
//Accessing the inner repeater control on ItemBound event of Parent Repeater Control
Repeater innerRepeater = (Repeater)e.Item.FindControl("innerRepeater");
//here e.Item basically refers to your RepeaterItem Class of the respective ItemTemplate
}
}
For accessing the elements within the inner Repeater Control we will be making use of an ItemDataBound event of the inner Repeater Control like the following.
protected void innerRepeater_ItemDataBound(object sender, RepeaterItemEventArgs e)
{
if (e.Item.ItemType == ListItemType.AlternatingItem || e.Item.ItemType == ListItemType.Item)
{
//Accessing the Labels control placed within the Child/Inner Repeater Control
Label lblEnglish = (Label)e.Item.FindControl("lblEnglish");
Label lblHindi = (Label)e.Item.FindControl("lblHindi");
Label lblMarathi = (Label)e.Item.FindControl("lblMarathi");
Label lblMaths = (Label)e.Item.FindControl("lblMaths");
Label lblScience = (Label)e.Item.FindControl("lblScience");
Label lblSocialScience = (Label)e.Item.FindControl("lblSocialScience");
float english = float.Parse(lblEnglish.Text);
float hindi = float.Parse(lblHindi.Text);
float marathi = float.Parse(lblMarathi.Text);
float maths = float.Parse(lblMaths.Text);
float science = float.Parse(lblScience.Text);
float socialScience = float.Parse(lblSocialScience.Text);
if (english < 35)
lblEnglish.CssClass = "failedClass";
if (hindi < 35)
lblHindi.CssClass = "failedClass";
if (marathi < 35)
lblMarathi.CssClass = "failedClass";
if (maths < 35)
lblMaths.CssClass = "failedClass";
if (science < 35)
lblScience.CssClass = "failedClass";
if (socialScience < 35)
lblSocialScience.CssClass = "failedClass";
ViewState["Total"] = english + hindi + marathi + maths + science + socialScience;
ViewState["Fail"] = english < 35 || hindi < 35 || marathi < 35 || science < 35 || maths < 35 || socialScience < 35 ? "Fail" : "";
}
else if (e.Item.ItemType == ListItemType.Footer)
{
if (ViewState["Total"] != null && ViewState["Fail"] != null)
{
Label lblTotal = (Label)e.Item.FindControl("lblTotal");
lblTotal.Text = ViewState["Total"].ToString();
Label lblResult = (Label)e.Item.FindControl("lblResult");
lblResult.Text = ViewState["Fail"].ToString();
lblResult.CssClass = ViewState["Fail"].ToString() == "" ? "edClass" : "failedClass";
}
}
}
The following are the SQL Queries that contains the tables used, procedures used etcetera:
create database Practice
use Practice
drop table Students
create table Students
(
StudId varchar(10),
RollNo int identity(1,1)not null,
StudName varchar(30),
StudAdd varchar(50),
StudCity varchar(50),
StudTel varchar(20),
constraint pkStudId primary key(StudId)
)
alter procedure prc_AddStudentDetails
(
@name varchar(30),
@add varchar(50),
@city varchar(50),
@telno varchar(20)
)
as
begin
declare @rno int
declare @studid varchar(10)
if(select COUNT(*) from students)>0
begin
select @rno=MAX(rollno)
from students
end
else
set @rno=0
set @studid='S00'+Convert(varchar,(@rno+1))
insert into Students(StudId,StudName,StudAdd,StudCity,StudTel)
values(@studid,@name,@add,@city,@telno)
end
prc_AddStudentDetails 'Vishal','Andheri','Mumbai','123456789'
prc_AddStudentDetails 'Dheeraj','Bhayandar','Mumbai','987654321'
prc_AddStudentDetails 'Shankar','Kalyan','Thane','456789123'
prc_AddStudentDetails 'Kailash','Santacruz','Mumbai','789123456'
prc_AddStudentDetails 'Jack','Dadar','Mumbai','852741963'
select * from Students
create table Marks
(
Rollno int,
English float,
Hindi float,
Marathi float,
Maths float,
Science float,
SocialScience float
)
select * from Marks
insert into Marks
values(1,85,75,95,99,95,89)
insert into Marks
values(2,65,85,88,83,98,80)
insert into Marks
values(3,55,85,85,85,65,79)
insert into Marks
values(4,95,90,90,88,75,99)
insert into Marks
values(5,80,88,89,90,92,88)
create procedure prc_GetStudentMarksData
as
begin
select StudId,a.RollNo,StudName,English,Marathi,Maths,Science,SocialScience,Hindi
from Students a inner join Marks b
on a.RollNo=b.Rollno
end
create procedure prc_GetStudentData
as
begin
select * from Students
end
create procedure prc_GetStudentMarks
(
@rollno int
)
as
begin
select * from Marks
where Rollno=@rollno
end
update Marks
set SocialScience=23
where Rollno=5
Let's check the design/mark up code for it.
<%@ Page Language="C#" AutoEventWireup="true" CodeFile="Default.aspx.cs" Inherits="_Default" %>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head runat="server">
<title></title>
<link rel="Stylesheet" type="text/css" href="myStyle.css" />
</head>
<body>
<form id="form1" runat="server">
<div>
<asp:Label ID="lblNoRecords" runat="server" Text="No Records Found" Visible="false"></asp:Label>
<asp:Repeater ID="Repeater1" runat="server" OnItemDataBound="Repeater1_ItemDataBound">
<HeaderTemplate>
<table class="w70 center">
<tr>
<td colspan="2" align="center" class="title">
Student's Report
</td>
</tr>
</HeaderTemplate>
<ItemTemplate>
<tr class="even">
<td>
Stud ID:
<asp:TextBox ID="txtStudID" Enabled="false" Text='<%#Eval("StudID") %>' runat="server"
CssClass="txtSmallEntry"></asp:TextBox>
</td>
<td>
Roll No:
<asp:TextBox ID="txtRollno" Enabled="false" Text='<%#Eval("Rollno") %>' runat="server"
CssClass="txtSmallEntry"></asp:TextBox>
</td>
</tr>
<tr class="even">
<td colspan="2">
Name:
<asp:TextBox ID="txtName" Enabled="false" Text='<%#Eval("StudName") %>' runat="server"
CssClass="txtEntry"></asp:TextBox>
</td>
</tr>
<tr class="even">
<td colspan="2">
<asp:Repeater ID="innerRepeater" runat="server" OnItemDataBound="innerRepeater_ItemDataBound">
<HeaderTemplate>
<table class="w50 left10">
</HeaderTemplate>
<ItemTemplate>
<tr>
<td class="center">
English:
</td>
<td>
<asp:Label ID="lblEnglish" CssClass="edClass" runat="server" Text='<%#Eval("English") %>'></asp:Label>
</td>
</tr>
<tr>
<td>
Hindi:
</td>
<td>
<asp:Label ID="lblHindi" CssClass="edClass" runat="server" Text='<%#Eval("Hindi") %>'></asp:Label>
</td>
</tr>
<tr>
<td>
Marathi:
</td>
<td>
<asp:Label ID="lblMarathi" CssClass="edClass" runat="server" Text='<%#Eval("Marathi") %>'></asp:Label>
</td>
</tr>
<tr>
<td>
Maths:
</td>
<td>
<asp:Label ID="lblMaths" CssClass="edClass" runat="server" Text='<%#Eval("Maths") %>'></asp:Label>
</td>
</tr>
<tr>
<td>
Science:
</td>
<td>
<asp:Label ID="lblScience" CssClass="edClass" runat="server" Text='<%#Eval("Science") %>'></asp:Label>
</td>
</tr>
<tr>
<td>
Social Science:
</td>
<td>
<asp:Label ID="lblSocialScience" CssClass="edClass" runat="server" Text='<%#Eval("SocialScience") %>'></asp:Label>
</td>
</tr>
</ItemTemplate>
<FooterTemplate>
<tr>
<td align="right">
Total:
<asp:Label ID="lblTotal" CssClass="totalClass" runat="server"></asp:Label>
</td>
<td class="right">
<asp:Label ID="lblResult" runat="server"></asp:Label>
</td>
</tr>
</table>
</FooterTemplate>
</asp:Repeater>
</td>
</tr>
</ItemTemplate>
<AlternatingItemTemplate>
<tr class="odd">
<td>
Stud ID:
<asp:TextBox ID="txtStudID" Enabled="false" Text='<%#Eval("StudID") %>' runat="server"
CssClass="txtSmallEntry"></asp:TextBox>
</td>
<td>
Roll No:
<asp:TextBox ID="txtRollno" Enabled="false" Text='<%#Eval("Rollno") %>' runat="server"
CssClass="txtSmallEntry"></asp:TextBox>
</td>
</tr>
<tr class="odd">
<td colspan="2">
Name:
<asp:TextBox ID="txtName" Enabled="false" Text='<%#Eval("StudName") %>' runat="server"
CssClass="txtEntry"></asp:TextBox>
</td>
</tr>
<tr class="odd">
<td colspan="2">
<asp:Repeater ID="innerRepeater" runat="server" OnItemDataBound="innerRepeater_ItemDataBound">
<HeaderTemplate>
<table class="w50 left10">
</HeaderTemplate>
<ItemTemplate>
<tr>
<td class="center">
English:
</td>
<td>
<asp:Label ID="lblEnglish" CssClass="edClass" runat="server" Text='<%#Eval("English") %>'></asp:Label>
</td>
</tr>
<tr>
<td>
Hindi:
</td>
<td>
<asp:Label ID="lblHindi" CssClass="edClass" runat="server" Text='<%#Eval("Hindi") %>'></asp:Label>
</td>
</tr>
<tr>
<td>
Marathi:
</td>
<td>
<asp:Label ID="lblMarathi" CssClass="edClass" runat="server" Text='<%#Eval("Marathi") %>'></asp:Label>
</td>
</tr>
<tr>
<td>
Maths:
</td>
<td>
<asp:Label ID="lblMaths" CssClass="edClass" runat="server" Text='<%#Eval("Maths") %>'></asp:Label>
</td>
</tr>
<tr>
<td>
Science:
</td>
<td>
<asp:Label ID="lblScience" CssClass="edClass" runat="server" Text='<%#Eval("Science") %>'></asp:Label>
</td>
</tr>
<tr>
<td>
Social Science:
</td>
<td>
<asp:Label ID="lblSocialScience" CssClass="edClass" runat="server" Text='<%#Eval("SocialScience") %>'></asp:Label>
</td>
</tr>
</ItemTemplate>
<FooterTemplate>
<tr>
<td align="right">
Total:
<asp:Label ID="lblTotal" CssClass="totalClass" runat="server"></asp:Label>
</td>
<td class="right">
<asp:Label ID="lblResult" runat="server"></asp:Label>
</td>
</tr>
</table>
</FooterTemplate>
</asp:Repeater>
</td>
</tr>
</AlternatingItemTemplate>
<FooterTemplate>
<tr>
<td colspan="2" align="center" style="margin-left: 3px;">
<asp:Button ID="btnFirst" OnClick="CommonButton_Click" runat="server" Text="<<" />
<asp:Button ID="btnPrevious" OnClick="CommonButton_Click" runat="server" Text="<" />
<asp:Button ID="btnNext" OnClick="CommonButton_Click" runat="server" Text=">" />
<asp:Button ID="btnLast" OnClick="CommonButton_Click" runat="server" Text=">>" />
</td>
</tr>
</table>
</FooterTemplate>
</asp:Repeater>
</div>
</form>
</body>
</html>
Source Code for it
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.UI;
using System.Web.UI.WebControls;
using System.Configuration;
using System.Data;
using System.Data.SqlClient;
public partial class _Default : System.Web.UI.Page
{
SqlConnection con;
DataSet ds;
SqlDataAdapter da;
SqlCommand cmd;
private string _dbCon = ConfigurationManager.ConnectionStrings["myCon"].ConnectionString;
//for paging within the repeater control
PagedDataSource pageDataSource = new PagedDataSource();
public int CurrentPage
{
get
{
if (ViewState["currentPage"] == null)
return 0;
else
return Convert.ToInt32(ViewState["currentPage"].ToString());
}
set
{
ViewState["currentPage"] = value;
}
}
protected void Page_Load(object sender, EventArgs e)
{
if (!IsPostBack)
GetStudentData();
}
/// <summary>
/// Get the Student Personal Data such as their ID,RollNo,
/// Name for displaying in the parent control
/// </summary>
private void GetStudentData()
{
con = new SqlConnection(_dbCon);
da = new SqlDataAdapter("prc_GetStudentData", con);
da.SelectCommand.CommandType = CommandType.StoredProcedure;
ds = new DataSet("myDs");
da.Fill(ds);
if (ds.Tables[0].Rows.Count > 0)
{
pageDataSource.DataSource = ds.Tables[0].DefaultView;
pageDataSource.CurrentPageIndex = CurrentPage;
pageDataSource.PageSize = 2;
pageDataSource.AllowPaging = true;
ViewState["totalPages"] = pageDataSource.PageCount;
Repeater1.DataSource = pageDataSource;
//on DataBind parent ItemDataBound event will be called
Repeater1.DataBind();
//For accessing the FooterTemplate controls.
RepeaterItem repeaterItem = (RepeaterItem)Repeater1.Controls[Repeater1.Controls.Count - 1];
Button btnFirst = (Button)repeaterItem.FindControl("btnFirst");
Button btnPrevious = (Button)repeaterItem.FindControl("btnPrevious");
Button btnNext = (Button)repeaterItem.FindControl("btnNext");
Button btnLast = (Button)repeaterItem.FindControl("btnLast");
btnPrevious.Enabled = btnFirst.Enabled = !pageDataSource.IsFirstPage;
btnLast.Enabled = btnNext.Enabled = !pageDataSource.IsLastPage;
}
else
lblNoRecords.Visible = true;
}
/// <summary>
/// Getting respective Student Marks Details of the Student by using their rollno
/// </summary>
/// <param name="rollNo">RollNo</param>
/// <returns>returns DataTable</returns>
private DataTable GetStudentMarks(string rollNo)
{
con = new SqlConnection(_dbCon);
da = new SqlDataAdapter("prc_GetStudentMarks", con);
da.SelectCommand.CommandType = CommandType.StoredProcedure;
da.SelectCommand.Parameters.AddWithValue("@rollno", rollNo);
DataTable dt = new DataTable();
da.Fill(dt);
return dt;
}
/// <summary>
/// Within this event we are trying to access the child or inner element of the Repeater Control
/// by using FindControl method
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
protected void Repeater1_ItemDataBound(object sender, RepeaterItemEventArgs e)
{
if (e.Item.ItemType == ListItemType.AlternatingItem || e.Item.ItemType == ListItemType.Item)
{
TextBox lblRollNo = (TextBox)e.Item.FindControl("txtRollno");
Repeater innerRepeater = (Repeater)e.Item.FindControl("innerRepeater");
DataTable dt = GetStudentMarks(lblRollNo.Text);
innerRepeater.DataSource = dt;
innerRepeater.DataBind();
}
}
/// <summary>
/// Childs ItemDataBound event for accessing the controls of the child/inner Repeater Control for performing some
/// logic such as if the student fails then his/her data should be displayed in red color.
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
protected void innerRepeater_ItemDataBound(object sender, RepeaterItemEventArgs e)
{
if (e.Item.ItemType == ListItemType.AlternatingItem || e.Item.ItemType == ListItemType.Item)
{
Label lblEnglish = (Label)e.Item.FindControl("lblEnglish");
Label lblHindi = (Label)e.Item.FindControl("lblHindi");
Label lblMarathi = (Label)e.Item.FindControl("lblMarathi");
Label lblMaths = (Label)e.Item.FindControl("lblMaths");
Label lblScience = (Label)e.Item.FindControl("lblScience");
Label lblSocialScience = (Label)e.Item.FindControl("lblSocialScience");
float english = float.Parse(lblEnglish.Text);
float hindi = float.Parse(lblHindi.Text);
float marathi = float.Parse(lblMarathi.Text);
float maths = float.Parse(lblMaths.Text);
float science = float.Parse(lblScience.Text);
float socialScience = float.Parse(lblSocialScience.Text);
if (english < 35)
lblEnglish.CssClass = "failedClass";
if (hindi < 35)
lblHindi.CssClass = "failedClass";
if (marathi < 35)
lblMarathi.CssClass = "failedClass";
if (maths < 35)
lblMaths.CssClass = "failedClass";
if (science < 35)
lblScience.CssClass = "failedClass";
if (socialScience < 35)
lblSocialScience.CssClass = "failedClass";
ViewState["Total"] = english + hindi + marathi + maths + science + socialScience;
ViewState["Fail"] = english < 35 || hindi < 35 || marathi < 35 || science < 35 || maths < 35 || socialScience < 35 ? "Fail" : "";
}
else if (e.Item.ItemType == ListItemType.Footer)
{
if (ViewState["Total"] != null && ViewState["Fail"] != null)
{
Label lblTotal = (Label)e.Item.FindControl("lblTotal");
lblTotal.Text = ViewState["Total"].ToString();
Label lblResult = (Label)e.Item.FindControl("lblResult");
lblResult.Text = ViewState["Fail"].ToString();
lblResult.CssClass = ViewState["Fail"].ToString() == "" ? "edClass" : "failedClass";
}
}
}
/// <summary>
/// Common Handler for all the button placed within the parent's footer row
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
protected void CommonButton_Click(object sender, EventArgs e)
{
Button b = (Button)sender;
switch (b.ID)
{
case "btnFirst":
CurrentPage = 0;
GetStudentData();
break;
case "btnPrevious":
CurrentPage -= 1;
GetStudentData();
break;
case "btnNext":
CurrentPage += 1;
GetStudentData();
break;
case "btnLast":
if (ViewState["totalPages"] != null)
{
CurrentPage = Convert.ToInt32(ViewState["totalPages"].ToString()) - 1;
GetStudentData();
}
break;
}
}
}
Finally it is time to check the output of it.
You could make use of Pagination also by simply clicking the next or last button on the first page or else the previous and first page if on the middle pages.
Where the Student Fails his/her subject then marks are displayed in the red color and also the /fail flag is displayed in the red color.
Hope you liked the article.