Click here to Skip to main content
65,938 articles
CodeProject is changing. Read more.
Articles / web / ASP.NET

One approach to data binding with nested Repeaters

3.29/5 (6 votes)
18 Apr 2008CPOL2 min read 1   172  
Binding a variable number of DataTable objects using nested Repeaters.

Introduction

This article is a small demo project that uses nested Repeaters to display a variable number of DataTable objects with the same schema.

Using the code

Before I continue, I realize that the following solution is not exactly the most elegant, but it works, and criticisms are most welcome.

We have two Repeater controls. The inner Repeater control is placed within a User Control, while the outer Repeater is contained with the APSX page, with its <ItemTemplate> being the User Control.

Before we go into the details of the controls, first, let’s introduce the small customDataItem.cs class in the App_Code folder. For some reason, when I bind a DataSet, the Repeaters do not render all of the tables as expected, but actually repeats the last DataTable in the set several times. So, the alternative approach was to encapsulate each of the DataTable object within a new object. So, I created a class called CustomDataItem.

C#
public class CustomDataItem 
{ 
    private DataTable _Data;
    public DataTable Data { get { return _Data; } set { _Data = value; } } 

    public CustomDataItem(DataTable data) 
    { 
        _Data = data; 
    } 
}

As you can see, it’s a very simple class that encapsulates a DataTable object passed as a parameter to the constructor. That’s it, basically.

Next, we have the User Control (.ascx) code that contains the inner Repeater. It’s fairly simple and self-explanatory. You will notice that I have a Literal control as a header. The Literal text will be set to the table name when data bound.

HTML
<h2><span><asp:Literal runat="server" ID="ltrTableName"/></span></h2> 
<asp:Repeater ID="innerRep" runat="server"> 
<HeaderTemplate> 
<table cellpadding="2" cellspacing="5" border="true"> 
<thead> 
<tr> 
<th><b>Name</b></th> 
<th><b>Address</b></th> 
<th><b>PostCode</b></th> 
</tr> 
</thead> 
</HeaderTemplate> 
<ItemTemplate> 
<tr> 
<td><%# DataBinder.Eval(Container.DataItem,"Name") %></td> 
<td><%# DataBinder.Eval(Container.DataItem,"Address") %></td> 
<td><%# DataBinder.Eval(Container.DataItem,"PostCode") %></td> 
</tr> 
</ItemTemplate> 
<FooterTemplate> 
</table> 
</FooterTemplate> 
</asp:Repeater>

Now, for the code-behind of the user control:

C#
public partial class InnerRepeaterUserControl : System.Web.UI.UserControl 
{
  private CustomDataItem _DataItem; 
  public CustomDataItem DataItem { get { return _DataItem; } 
                                 set { _DataItem = value; } }
  protected void Page_Load(object sender, EventArgs e) 
  { 
    if (!IsPostBack) 
         BindData(); 
  }
  protected override void OnPreRender(EventArgs e) 
  { 
    base.OnPreRender(e); 
  } 
  private void BindData() 
  { 
    try 
    { 
         binnerRep.DataSource = _DataItem.Data;
         innerRep.DataBind(); 
         ltrTableName.Text = _DataItem.Data.TableName; 
    } 
    catch { }
  }

The BindData() method binds the DataTable contained within the CustomDataItem object and the Literal text to the table name. The CustomDataItem is passed in the innerRepeater_DataBound() event fired on the main ASPX page. We will go into details a little later on.

The ASPX code on the web page is simple enough. Here, all we do is register the user control and add the outer Repeater, as well as set the reference to the outer Repeater's ItemDataBound method.

ASP.NET
<%@ Page Language="C#" AutoEventWireup="true" 
         CodeFile="Default.aspx.cs" Inherits="_Default" %> 
<%@ Register Src="~/InnerRepeaterUserControl.ascx" 
         TagPrefix="uc" TagName="InnerRep" %> 
<!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>Repeater Demo</title> 
</head> 
<body> 
<form id="form1" runat="server"> 
<div> 
<asp:Repeater runat="server" ID="outerRepeater" 
       onItemDataBound="outerRepeater_ItemDataBound"> 
<ItemTemplate> 
<uc:InnerRep runat="server" ID="tblInnerRep" />
</ItemTemplate> 
</asp:Repeater> 
</div> 
</form> 
</body> 
</html>

The C# code-behind of the web page is where most of the work is done. In this example, I created three simple data tables in the code in createDataTables(), and added them to a generic list of CustomDataItem objects.

BindData() simply calls the method and binds the list to the outer Repeater.

Finally, in outerRepeater_ItemDataBound, we find the inner Repeater control, cast the e.DataItem of the outer Repeater to a CustomDataItem, and set this as the inner Repeater's DataItem.

C#
protected void Page_Load(object sender, EventArgs e) 
{ 
    if (!Page.IsPostBack) 
    { 
         base.OnInit(e); 
         BindData(); 
     } 
} 
private void BindData() 
{ 
    List<CustomDataItem> dataItems = createDataTables(); 
    outerRepeater.DataSource = dataItems; 
    outerRepeater.DataBind(); 
} 
private List<CustomDataItem> createDataTables() 
{ 
    //instantiate Generic list & set capacity to 3 
    List<CustomDataItem> dataItems = new List<CustomDataItem>(3); 
    // Logic for creating example DataTable objects here 
    //....... 
    //....... 
    //create new CustomDataItems and add to List<> 
    dataItems.Add(new CustomDataItem(tbl1)); 
    dataItems.Add(new CustomDataItem(tbl2)); 
    dataItems.Add(new CustomDataItem(tbl3)); 
    return dataItems; 
} 

protected void outerRepeater_ItemDataBound(object sender, RepeaterItemEventArgs e) 
{ 
    if (e.Item.DataItem is CustomDataItem) 
    { 
           CustomDataItem dataItem = e.Item.DataItem as CustomDataItem; 
           InnerRepeaterUserControl ctrl = 
                 e.Item.FindControl("tblInnerRep") as InnerRepeaterUserControl; 
           if (ctrl != null) 
               ctrl.DataItem = dataItem; 
     } 
}

Points of interest

None.

History

No changes.

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)