Click here to Skip to main content
Click here to Skip to main content

Nesting Repeaters with Hierarchical Data and Server-Binding

, 5 May 2005
Rate this:
Please Sign up or sign in to vote.
You can find fragments about nesting Repeaters online, but these methods demystify this elusive .NET control.

Introduction

Ever questioned the implementation of the Repeater control? Yes we've all had requirements where this control comes in handy. The thing that detracted me and many developers I've spoken with is the use of DataBinder.Eval in the front end code. There are online examples that attempt to explain everything that needs to happen to move the binding logic to the compiled code, but once more, I learned that I had to figure out the details on my own. Next time you need the repeater functionality, stop struggling with HTML in the code to generate your output, and wincing at DataBinder.Eval in the front end code. When you understand these method's you'll be satisfied with the repeater at last.

Front end code

The front end code with these methods is very light and simple. The only catch is to make sure you import the System.Data namespace. Even with this method, we need to use DataRowView in the front end. Take a special note: when you nest these Repeaters, the designer will whine like a baby in a two dollar crib.

To pacify the baby, you need to comment out the parent Repeater, if you want to return to the designer to work with other controls. You better know markup language, if you can't code this by hand, you're already in over your head. In that case, I would recommend w3schools.com Smile | :) .

Please note that the tag "sItemTemplate" is really supposed to be "ItemTemplate" but something about the CodeProject rejects that in the code block.

Also note that the front end does not care about the DataSource. The container knows what source to choose for your column-name keys upon binding. You may proceed to the server code now:

<%@ Control Language="c#" AutoEventWireup="false" 
  Codebehind="NestedRepeater.ascx.cs" 
  Inherits="YourProject.UserControls.NestedRepeater" 
  TargetSchema="http://schemas.microsoft.com/intellisense/ie5"%>
<%@ Import namespace="System.Data" %>
<asp:Repeater id="AreaResults" 
  OnItemDataBound="AreaResults_ItemDataBound" 
  runat="server">
    <headerTemplate>
      <table border="0" cellpadding="0" cellspacing="0">
    </headerTemplate>
    <sItemTemplate>
      <tr>
        <td valign="top">
          <A href="?AreaID=<%# ((DataRowView)Container.DataItem)[" AreaID?]%>?>
            <img border="0" 
              src="<%# ((DataRowView)Container.DataItem)["ImageLink"]%>" 
              hspace="3px" vspace="3px" alt="View Area Detail">
          </a>
        </td>
        <td>
          <A href="?AreaID=<%# ((DataRowView)Container.DataItem)[" AreaID?]%>?>
          <%# ((DataRowView)Container.DataItem)["AreaName"]%></A> - 
          <%# ((DataRowView)Container.DataItem)["AreaDescription"]%>
             <asp:Repeater id="PropertyResults" runat="server">
                <headerTemplate>
                     <table border="0" cellpadding="0" cellspacing="0">
                </headerTemplate>
                <sItemTemplate>
                  <tr>
                    <td>
                     <a href='?PropertyID=<%# ((DataRowView)
                                           Container.DataItem)["PropertyID"]%>'>
                       <%# ((DataRowView)Container.DataItem)["PropertyName"]%>
                     </a>
                    </td>
                    <td width="10"></td>
                    <td>
                     <%# ((DataRowView)Container.DataItem)["DistanceToCentroid"]%>
                    </td>
                  </tr>
                <s/ItemTemplate>
                <FooterTemplate>
                    <tr>
                      <td colspan="3" height="10"></td>
                    </tr>
                   </table>
                </FooterTemplate>
             </asp:Repeater>
        </td>
      </tr>
    </sItemTemplate>
    <FooterTemplate>
        </table>
    </FooterTemplate>
</asp:Repeater>

Server code

I have given you one generic method that handles your data and binding, only to illustrate the necessary steps. I'm quite sure, you are a master of your data at this point so I've excluded impertinent details about data retrieval and manipulation. Pay special attention to the comments.

        protected void massageData()
        {
            DataSet resultSet = new DataSet("resultSet");
            DataTable AreaDT = new DataTable("AreaDT");
            DataTable PropertyDT = new DataTable("PropertyDT");
            
            /*
             * Populate your data tables with your chosen method
             * */

            //Add DataTables to DataSet and create the one-to-many 
            //relationships (as many as you need)
            resultSet.Tables.Add(AreaDT);
            resultSet.Tables.Add(PropertyDT);
            resultSet.Relations.Add("PropertiesInArea",
                AreaDT.Columns["AreaID"],PropertyDT.Columns["AreaID"]);

            /* Important!!!  Only set the data source for the 
             *  topmost parent in the heirarchy.
             * The nested repeaters that are buried in the topmost 
             *  parent will not be in scope until binding
             * when using this server-style binding method. */ 

            AreaResults.DataSource = resultSet.Tables["AreaDT"];

            //Upon databind, you invoke the ItemDataBound Method, 
            //which can be easily created by the events tab
            //under the properties of the repeater control in the designer
            AreaResults.DataBind();
            AreaResults.Visible = true;
        }

Now for the goodies. You have specified an OnItemDataBound method in your front end code, so it is time to own up to your promise and provide the method for your fickle and whiny front end code:

protected void AreaResults_ItemDataBound(object sender, 
                    System.Web.UI.WebControls.RepeaterItemEventArgs e)
{
    //Only consume the items in the parent repeater 
    //pertinent to nesting
    if (e.Item.ItemType == ListItemType.Item || 
              e.Item.ItemType == ListItemType.AlternatingItem)
    {
        //Now that the nested repeater is in scope, find it, 
        //cast it, and create a child view from
        //the datarelation name, and specify that view as the 
        //datasource.  Then bind the nested repeater!
        Repeater tempRpt = 
               (Repeater)e.Item.FindControl("PropertyResults");
        if (tempRpt != null)
        {
           tempRpt.DataSource = 
             ((DataRowView)e.Item.DataItem).CreateChildView("PropertiesInArea");
           tempRpt.DataBind();
        }
    }
}

Voila! The Repeater looks much more manageable and elegant to me now!

License

This article has no explicit license attached to it but may contain usage terms in the article text or the download files themselves. If in doubt please contact the author via the discussion board below.

A list of licenses authors might use can be found here

Share

About the Author

Thomas Kurek
Web Developer
United States United States
Broad engineering background, Virginia Tech Alum. Attracted to .NET by the sheer power of the framework and elegance of c#. Work includes analytical system to calculate joint torque during balance recovery to recommend physical therapy routines and correct bad biomechanics (preventative medicine). Assimilated force plate and 3D kinematic data for modeling. First and sole developer ever to fully automate corporate housing quotes, which I built into a larger engine that serves the company's entire enterprise.
 
Experience with applications architecture, DB design and UML 2.0. Experience with a broad range of applied mathematics, FEM software coding, solid and fluid mechanics. Great knowledge of healthcare and physiology with degree in Mechanical/Electrical/Materials Engineering Theory (Engineering Science and Mechanics) and concentration in biomechanics.
 
Currently expanding my corporate housing business engine by day. By night I am expanding my software engineering design and construction knowledge, staying in touch with the direction of healthcare management systems, and moving music business technology forward. Microsoft is now working on blowing iTunes out of the water, but my business is making an even bigger revolution that is far beyond just music retail. It strikes at the heart of the music industry's issues, and perhaps we will consider partnering with Microsoft to feed their music retail goals while they feed our music licensing, publishing, and digital decentralization of distribution.
 
I am the Enterprise Architect at my company and maintain a small but powerful and effective team. I have personally customized CxOne from construx (www.construx.com) for this team. Long live Steve McConnell.

Comments and Discussions

 
QuestionI have a problem when use printed review to check nested repeater aspx pages PinmemberYingHsuan25-Nov-07 23:29 
AnswerRe: I have a problem when use printed review to check nested repeater aspx pages PinmemberYingHsuan27-Nov-07 5:46 
GeneralNested Repeaters - Commnd EventHandler PinmemberJoel Blankchtein26-Jul-06 21:06 
GeneralFactoring out those pesky &quot;((DataRowView)Container.DataItem)&quot; clauses :) PinmemberBeej12611-May-05 5:54 
GeneralRe: Factoring out those pesky &quot;((DataRowView)Container.DataItem)&quot; clauses :) PinmemberThomas Kurek11-May-05 6:29 

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Rant Rant    Admin Admin   

Use Ctrl+Left/Right to switch messages, Ctrl+Up/Down to switch threads, Ctrl+Shift+Left/Right to switch pages.

| Advertise | Privacy | Terms of Use | Mobile
Web04 | 2.8.141223.1 | Last Updated 5 May 2005
Article Copyright 2005 by Thomas Kurek
Everything else Copyright © CodeProject, 1999-2014
Layout: fixed | fluid