Web Forms Server Controls Programming Web Forms Server Controls Accessing Server Controls Programmatically
When you declare an ID attribute on a Web Forms control to provide programmatic access to that control, the Web Forms page framework automatically ensures that the ID you declare will be unique across your entire ASP.NET Web application.
The Web Forms page framework provides your applications with automatic control ID resolution through the INamingContainer interface, which generates a naming container for each class that implements it. A naming container logically defines a new ID namespace within a Web Forms page control hierarchy. A naming container then allows a page framework to generate the UniqueID property of the Control class to be generated for each control within that namespace. The UniqueID property is different from the ID property that you declare on a control in that it is the fully-qualified identifier for a control. A control’s UniqueID necessarily contains that control’s ID property value.
The classes that implement the INamingContainer include: Page, DataList, DataGrid, DataListItem, DataGridItem, and Repeater. When a page is compiled on request, the Page class serves as the top-level naming container for that page’s control hierarchy.
It is in data binding scenarios, however, when the automatic naming resolution provided by the page framework really becomes important. Consider the following controls declared on a page.
<asp:Repeater id="myList" runat="server">
<itemtemplate>
<asp:Label id="myLabel" Text='<%# Container.ToString ( ) %>"
runat="server"/><br>
</itemtemplate>
</asp:Repeater>
When the Label control is bound to a data source and the Repeater control iterates over the items from that source, the system must distinguish programmatically between the different instances of the Label control, even though you have only been able to assign myLabel as the ID value for each instance. The system then uses the fully qualified UniqueID property for each control. For example, the following code, which includes the fragment above, generates three versions of the Label control and writes their UniqueIDs to the displayed page.
<html>
<script language="C#" runat="server">
void Page_Load ( object src, EventArgs e ) {
Response.Write ( "Container: " +
myList.NamingContainer.ToString ( ) + "<p>" );
ArrayList a = new ArrayList ( );
a.Add ( "A" );
a.Add ( "B" );
a.Add ( "C" );
myList.DataSource = a;
myList.DataBind ( );
for ( int i = 0; i < myList.Controls.Count; i++ ) {
Label l= ( Label ) ( ( RepeaterItem )
myList.Controls [ i ] ) .FindControl ( "myLabel" );
Response.Write ( "Container: " + ( ( RepeaterItem )
myList.Controls [ i ] ) .NamingContainer.ToString ( ) + "<p>" );
Response.Write ( "<b>" + l.UniqueID + "</b><p>" );
}
}
</script>
<body>
<p><asp:Repeater id="myList" runat="server">
<itemtemplate>
<asp:Label id="myLabel" Text='<%# Container.ToString ( ) %>"
runat="server"/><br>
</itemtemplate>
</asp:Repeater>
</body>
</html>
When this page is requested, it first writes the naming container of the myList Repeater control, the page, to the browser. This naming container depends upon the name given .aspx file.
NOTE: If the .aspx file for this example were mySample1.aspx, the class of the naming container would be ASP.mysample1_aspx, but the naming of the naming container would be Page.
It next writes the instance of the next control that serves as a naming container, the Repeater object. This container name is displayed with its entire namespace qualifier, so it is System.Web.UI.WebControls.Repeater. Next the page displays the UniqueID property of the myLabel Label control. This is repeated three times, once for each entry in the ArrayList defined in the code declaration block. The values for each of these Label objects would be myList:Ctrl0:myLabel, myList:Ctrl1:myLabel, and myList:Ctrl2:myLabel, respectively.
Web Forms Control Identification Using the FindControl Method