Welcome to AspAdvice Sign in | Join | Help

Understanding the naming container hierarchy of ASP.NET databound controls

Some of the most common questions about ASP.NET data-bound controls are related to the naming container hierarchy. People are using databound controls but don't understand how these are designed to construct their control hierarchy which leads to problems in scenarios when these controls should be iterated or some functional stuff should be achieved. With data-bound controls I mean Repeater, DataList, DataGrid and GridView.

Assume I have a Repeater with following structure and it's databound to a data source with three rows.

<asp:repeater ID="Repeater1" runat="server" >
            <ItemTemplate>
                <asp:Button ID="Button1" runat="server" OnClick="Button1_Click" Text="Button on row" />
                <asp:TextBox ID="TextBox1" runat="server" Text="Text on row" />
                <br />
            </ItemTemplate>
        </asp:repeater>


[C#]

protected void Page_Load(object sender, EventArgs e)
    {
        if (!Page.IsPostBack)
        {
            ArrayList arr = new ArrayList();
            arr.Add(1);
            arr.Add(2);
            arr.Add(3);

            Repeater1.DataSource = arr;
            Repeater1.DataBind();
        }
    }

//We'll check later what's on Button1_Click

Essentially this builds control structure looking like this (there would be other controls like literal controls etc but I'll focus on the relevant ones)

OK, lets briefly describe what this means. Repeater has as many RepeaterItems as there were rows in the data source it was bound to. Every RepeaterItem contains the controls given in <ItemTemplate>. Basically this template was instantiated three times, once for every RepeaterItem. repeaterItems are accessible via Items collection property of the Repeater.

RepeaterItem is so called naming container, a control which implements INamingContainer interface.This means it provides unique naming scope for its child controls so that these won't have unique ids conflicting with other controls on the Page. In this case it of course means that repeated controls given in <ItemTemplate> all do have consistently unique id, accessible from control's UniqueID property. If you see how these are rendered in the previous example:

<input type="submit" name="Repeater1$ctl00$Button1" value="Button on row" id="Repeater1_ctl00_Button1" />
<input name="Repeater1$ctl00$TextBox1" type="text" value="Text on row" id="Repeater1_ctl00_TextBox1" />
<br />
           
<input type="submit" name="Repeater1$ctl01$Button1" value="Button on row" id="Repeater1_ctl01_Button1" />
<input name="Repeater1$ctl01$TextBox1" type="text" value="Text on row" id="Repeater1_ctl01_TextBox1" />
<br />
           
<input type="submit" name="Repeater1$ctl02$Button1" value="Button on row" id="Repeater1_ctl02_Button1" />
<input name="Repeater1$ctl02$TextBox1" type="text" value="Text on row" id="Repeater1_ctl02_TextBox1" />
<br />

Rendered name attributes correspond to UniqueID property and id attribute to ClientID property. What's clear also is that control's id is got by appending its id to ids of its ancestor controls (unique ID separator being $, client id the underscore _ ).

The usual scenarios this information is needed in

1. Access a specific control(s) on the databound control

If you need to access for example TextBox1 in previous example, you cannot do it by typing just TextBox1.xxx and assuming that ASP.NET would know which one of these TextBoxes you mean. As is probably clear from the picture, there are now multiple TextBoxes with ID 'TextBox1' and you need to be more accurate in telling which one you do want to access.

You can iterate through the Repeater1 and access the TextBoxes one by one.

 foreach (RepeaterItem rptItem in Repeater1.Items)
        {
            TextBox textbox = (TextBox)rptItem.FindControl("TextBox1");
           //Do something with the TextBox
        }

2. Access other controls on the same item

If you have reference to a control on the item, or you are typing code to event handler raised by an control on the item, you can use that control's reference to "gather" knowledge about on which item you are. To be clear, if you handle Button's click event in Button1_Click method (wired to Button on the Repeater) you can get the parent RepeaterItem via NamingContainer property of the Button. Another important piece of knowledge is that you get reference to the Button via sender argument in Button1_Click, because sender always provides the specific object which raised the event. In code:

protected void Button1_Click(object sender, EventArgs e)
    {
        Button btn = (Button)sender;
        RepeaterItem ritem = (RepeaterItem)btn.NamingContainer;
        //use the RepeaterItem to locate other controls on the row
        //...
      
    }

So, any control has reference to its naming container via NamingContainer property and this is very handy with databound controls. It applies equally to any of them. This technique is useful for example when you want to know the data key related to the item/row the control is on.

Note: Another way to deal with the click would've been using Command event relying to event bubbling, e.g specifying CommandName on the Button which eventually raises ItemCommand event. Point is that in ItemCommand event, the specific item is passed via command event arguments. However, Command event applies only to Buttons while this technique works for any type of control.

3. Use the information about the item type in databinding expressions

You know you are using a Repeater and it's item type is RepeaterItem. You know you get the item index via ItemIndex property so you can have this kind of databinding expression to provide running count number for items (rows)

<%#((RepeaterItem)Container).ItemIndex + 1 %>

With databinding expression you've probably seen the keyword Container multiple times. It refer's to the naming container we are currently on, and based on previous information you realize it just means it is reference to the item of the databound control which's context the databinding expression is evaluated in. You can cast the Container to the correct item type for early-bound access (in VS2005 this gives you intellisense with inline code too). In .NET 2.0 these all implement System.Web.UI.IDataItemContainer interface which gives access to certain important properties general to all item types.

Note: You've probably seen also Container being used multiple times in databinding expressions to access the DataItem property of the item in question. DataItem property is the row in data source being associated with the item type. Basically it is the data source row/item to which the item in the databound control is bound to/corresponds to. If you bind your control to a DataSet/DataTable or DataView the type of DataItem is System.Data.DataRowView. With data readers it is System.Data.Common.DbDataRecord. This is useful information even if you are using data source controls, since these provide just server control wrappers for the previously mentioned ADO.NET objects

About the databound controls

It's important to recognize that all databound controls are equal to this matter. They work in same way and have similar API. Their row/item types vary, but provide the same means for developer to utilize them. Here's list of databound controls and their corresponding row types

Repeater - System.Web.UI.WebControls.RepeaterItem
DataList - System.Web.UI.WebControls.DataListItem
DataGrid - System.Web.Ui.WebControls.DataGridItem
GridView - System.Web.UI.WebControls.GridViewRow

Published Sunday, February 25, 2007 11:28 AM by joteke
Filed under:

Comment Notification

If you would like to receive an email when updates are made to this post, please register here

Subscribe to this post's comments using RSS

Comments

# re: Understanding the naming container hierarchy of ASP.NET databound controls

Good article! What if your button is inside some kind of naming container and that is inside the repeater. Do you need to do: Container.Container?
Sunday, February 25, 2007 5:56 PM by Mike

# Four Helpful Features to Add to Your Base Page Class

Four Helpful Features to Add to Your Base Page Class

Saturday, February 21, 2009 9:46 PM by Continuous.Integration

# re: Understanding the naming container hierarchy of ASP.NET databound controls

This is absolutely fascinate.
Tuesday, March 03, 2009 7:34 AM by Shazia

# re: Understanding the naming container hierarchy of ASP.NET databound controls

I want to thank the author for this amazing piece of information. This has helped me alot during my first project on ASP.NET, thanks again.
Monday, July 13, 2009 11:12 AM by Jatinpreet Singh

# re: Understanding the naming container hierarchy of ASP.NET databound controls

A very conceptual blog!
Tuesday, August 18, 2009 1:00 PM by Vibhu

# re: Understanding the naming container hierarchy of ASP.NET databound controls

Thank you for a clear explanation of this subject.
Tuesday, August 25, 2009 11:38 PM by G

# re: Understanding the naming container hierarchy of ASP.NET databound controls

This is very informative article. I have two questions: 1) Can you please elaborate on DataItem property with example. 2) In a note you had mentioned "using Command event relying to event bubbling". Would appreciate if you can elaborate on this. Many Thanks.
Wednesday, October 21, 2009 2:41 PM by Geetika

# re: Understanding the naming container hierarchy of ASP.NET databound controls

Best Article. Thanx 4 sharing...
Saturday, November 14, 2009 12:39 AM by Kavindra Uniyal

# re: Understanding the naming container hierarchy of ASP.NET databound controls

Really very nice article.thanx for giving such type of article.
Thursday, January 21, 2010 3:01 AM by Sunny

# re: Understanding the naming container hierarchy of ASP.NET databound controls

thanks good article
Monday, February 01, 2010 4:37 AM by thecoder

# re: Understanding the naming container hierarchy of ASP.NET databound controls

good article.....n easy to understand
Wednesday, March 17, 2010 5:46 AM by mona

# re: Understanding the naming container hierarchy of ASP.NET databound controls

Very nice article.. You rocked
Friday, May 28, 2010 6:43 AM by Anil Kumar

Leave a Comment

(required) 
required 
(required) 
Enter the code you see below