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.

<asp:Repeater id="MyDataList" runat="server">
  <ItemTemplate>
    <asp:Label id="MyLabel" Text="<%# Container.ToString() %>" runat="server"/><br />
  </ItemTemplate>
</asp:Repeater>
<hr />
<asp:Label id="ResultsLabel" runat="server" AssociatedControlID="MyDataList"/>
<asp:Repeater id="MyDataList" runat="server">
  <ItemTemplate>
    <asp:Label id="MyLabel" Text="<%# Container.ToString() %>" runat="server"/><br />
  </ItemTemplate>
</asp:Repeater>
<hr />
<asp:Label id="ResultsLabel" runat="server" AssociatedControlID="MyDataList"/>

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 valuesto the page.

  <script language="vb" runat="server">

      Sub Page_Load(ByVal sender AsObject, ByVal e As EventArgs)
          Dim sb AsNew StringBuilder()
          sb.Append("Container: " + _
          MyDataList.NamingContainer.ToString() + "<p>")

          Dim a AsNew ArrayList()
          a.Add("A")
          a.Add("B")
          a.Add("C")

          MyDataList.DataSource = a
          MyDataList.DataBind()

          Dim i AsIntegerDim l As Label
          For i = 0 To MyDataList.Controls.Count - 1
              l = CType(CType(MyDataList.Controls(i), RepeaterItem).FindControl("MyLabel"), Label)
              sb.Append("Container: " & _
                 CType(MyDataList.Controls(i), RepeaterItem).NamingContainer.ToString() & _
                 "<p>")
              sb.Append("<b>" & l.UniqueID.ToString() & "</b><p>")
          Next
          ResultsLabel.Text = sb.ToString()
      EndSub
</script>
<script language="c#" runat="server">

  void Page_Load(Object sender, EventArgs e) 
  {
      StringBuilder sb = new StringBuilder();
      sb.Append("Container: " + 
          MyDataList.NamingContainer.ToString() + "<p>");

      ArrayList a = new ArrayList();
      a.Add("A");
      a.Add("B");
      a.Add("C");

      MyDataList.DataSource = a;
      MyDataList.DataBind();

      for (int i = 0; i < MyDataList.Controls.Count; i+)
      {
          Label l = 
              (Label)((RepeaterItem)MyDataList.Controls[i]).FindControl("MyLabel");
          sb.Append("Container: " + 
              ((RepeaterItem)MyDataList.Controls[i]).NamingContainer.ToString() + 
              "<p>");
          sb.Append("<b>" + l.UniqueID + "</b><p>");
      }
      ResultsLabel.Text = sb.ToString();
}
</script>

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.

See Also

Tasks

How to: Locate Controls by ID in an ASP.NET Web Page

How to: Access Members of a Web Server Control's Naming Container

Concepts

ASP.NET Web Server Controls Overview

Using the NamingContainer Property to Determine a Control's Naming Container