Web Forms Control ID Resolution The Naming Container Name Resolution in Data-Binding Scenarios ID Resolution Examples Examples of Visual C# ASP.NET ID Resolution Examples of Visual Basic ASP.NET ID Resolution ID Resolution Examples Examples of Visual C# ASP.NET ID Resolution Examples of Visual Basic ASP.NET ID Resolution See Also Tasks Concepts Sources and References
Web Forms Control ID Resolution
When you declare an ID attribute on a Web server control to provide programmatic access to that control, the ASP.NET page framework automatically ensures that the ID you declare will be unique across your entire ASP.NET Web application.
The Naming Container
The ASP.NET 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 defines a new ID namespace within an ASP.NET Web page control hierarchy. A naming container then allows the page framework to generate a value for the UniqueID property of each Control object generated within that namespace. The UniqueID property is different from the ID property that you declare in that it is the fully qualified identifier for a control.
The classes that implement INamingContainer include: Page, DataList, GridView, DataListItem, DataGridItem, and Repeater. In general, controls that can create child controls dynamically implement INamingContainer.
The Page class serves as the top-level naming container for that page's control hierarchy.
Name Resolution in Data-Binding Scenarios
The automatic naming resolution provided by the page framework becomes important in data-binding scenarios. Consider the following example, which shows controls declared on a page.
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head id="Head1" runat="server">
<title>Sample Page</title>
<meta http-equiv="Content-Type" content="text/html;charset=utf-8">
<%@ Page Language="vb"%>
<script runat="server" >
public sub Page_Load()
Dim myStringArray as String()
myStringArray = new String() {"one","two","three"}
rptr.DataSource = myStringArray
rptr.DataBind()
MyDataList.DataSource = myStringArray
MyDataList.DataBind()
MyDataList1.DataSource = myStringArray
MyDataList1.DataBind()
end sub
Protected Sub OnItemCreated(ByVal sender As Object, ByVal e As RepeaterItemEventArgs)
If (e.Item.ItemType = ListItemType.Item or e.Item.ItemType = ListItemType.AlternatingItem) Then
Dim item As RepeaterItem = e.Item
Dim customerId As Control = item.FindControl("MyLabel")
OnItemCreatedMyLabel.Text=TryCast(customerId, Label).ClientID.ToString()
End If
End Sub
Protected Sub OnItemDataBound(ByVal sender As Object, ByVal e As RepeaterItemEventArgs)
If (e.Item.ItemType = ListItemType.Item or e.Item.ItemType = ListItemType.AlternatingItem) Then
Dim item As RepeaterItem = e.Item
Dim customerId As Control = item.FindControl("MyLabel")
OnItemDataBoundMyLabel.Text=TryCast(customerId, Label).ClientID.ToString()
End If
End Sub
Private Function FindControlRecursive(ByVal rootControl As Control, ByVal controlID As String) As Control
If rootControl.ID = controlID Then
Return rootControl
End If
For Each controlToSearch As Control In rootControl.Controls
Dim controlToReturn As Control = FindControlRecursive(controlToSearch, controlID)
If controlToReturn IsNot Nothing Then
Return controlToReturn
End If
Next
Return Nothing
End Function
</script>
</head>
<body>
<%Response.Write("<p>Results on "& Request.ServerVariables("SERVER_SOFTWARE") & " .net: " & System.Environment.Version.ToString & " " & ScriptEngine & " Version " & ScriptEngineMajorVersion & "." & ScriptEngineMinorVersion & "</p>")%>
<asp:repeater id=rptr runat="server">
<itemtemplate>Container.DataItem: <%# Container.DataItem %><br></itemtemplate>
</asp:repeater>
<hr />
<asp:repeater id="MyDataList" runat="server">
<ItemTemplate>
Container.ToString(): <asp:Label id="MyLabel" Text="<%# Container.ToString() %>" runat="server"/><br />
</ItemTemplate>
</asp:repeater>
<hr />
<asp:Label id="ResultsLabel" runat="server" AssociatedControlID="MyDataList"/>
<hr />
<asp:repeater id="MyDataList1" runat="server" OnItemCreated = "OnItemCreated" OnItemDataBound = "OnItemDataBound">
<ItemTemplate>
Container.ItemIndex: <asp:Label id="MyLabel" Text="<%# Container.ItemIndex %>" runat="server"/><br />
</ItemTemplate>
</asp:repeater>
<hr />
<asp:Label id="ResultsLabel1" runat="server" AssociatedControlID="MyDataList1"/>
<hr />
The identifications of MyLabel:
<hr />
FindControlRecursive(MyDataList,"MyLabel").ID: <%=FindControlRecursive(MyDataList,"MyLabel").ID %><br />
FindControlRecursive(MyDataList1,"MyLabel").ID: <%=FindControlRecursive(MyDataList1,"MyLabel").ID %><br />
FindControlRecursive(MyDataList,"MyLabel").ClientID: <%=FindControlRecursive(MyDataList,"MyLabel").ClientID %><br />
FindControlRecursive(MyDataList1,"MyLabel").ClientID: <%=FindControlRecursive(MyDataList1,"MyLabel").ClientID %><br />
MyDataList1.OnItemCreated: <asp:Label id="OnItemCreatedMyLabel" Text="" runat="server"/><br />
MyDataList1.OnItemDataBound: <asp:Label id="OnItemDataBoundMyLabel" Text="" runat="server"/><br />
<hr />
</body>
</html>
When the Label control is bound to a data source and the Repeater control iterates through the items from that data source, the page must be able distinguish programmatically the different instances of the Label control, even though you have assigned only the ID MyLabel to each instance. The page framework does this by using the fully qualified UniqueID property for each control. For example, the following code generates three versions of the Label control and writes their UniqueID property values to the page.
When this page is requested, it writes the following to the page:
The naming container of the Repeater control named MyDataList. This naming container depends upon the name given to the .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 container would be Page.
The instance of the next control that serves as a naming container, namely the Repeater control. This container name is displayed with its entire namespace qualifier.
The UniqueID property of each Label control inside the Repeater control.
Note
Do not write code that references controls using the value of the generated UniqueID property. You can treat the UniqueID property as a handle (for example, by passing it to a process), but you should not rely on it having a specific structure.