The Web Forms framework allows page developers to assign a unique ID attribute to each server control on a page for programmatic reference. The ID attribute allows the framework to locate and manipulate any given control on a page. Controls that are not assigned an ID attribute by the developer are automatically assigned one by the page framework.
Server controls that provide built-in repetition capabilities (for example, repeaters and datagrids) expose templates that can contain other server controls. For example, the following fragment shows a repeater control that contains a span in its itemtemplate. In this example, there will be three span controls on the page because there are three data items in the repeater control's data source.
<html> <script language=”C#” runat=server> private void Page_Load(Object sender, EventArgs e) { MyRepeater.Datasource = { “One”, “Two”, “Three” }; MyRepeater.Databind(); } </script> <body> <form action=”Repeater.aspx” method=”Post” runat=server> <asp:repeater id=”MyRepeater” runat=server> <template:itemtemplate> <span id=”Message” runat=server> <%# Container.DataItem %> </span> </template:itemtemplate> </asp:repeater> </form> </body> </html>
In this case, the developer cannot provide a unique ID for an individual span control, only for all the span controls in common. To extend unique naming services in such scenarios, the Web Forms control framework supports the notion of NamingContainers. NamingContainers are server controls that implement the INamingContainer marker interface. Any NamingContainer on a page logically defines a new ID namespace hierarchy within the control tree. A control’s UniqueID property is guaranteed to be unique among all controls that share its NamingContainer within the tree. The UniqueID property provides read-only access to the fully qualified hierarchical identifier for a control. It consists of the naming container’s ID concatenated before the control’s local ID property.
In the code above, while the local ID property of each of the span controls is Message, the actual fully qualified UniqueID values of the controls are actually: MyRepeater:RepeaterRow0:Message, MyRepeater:RepeaterRow1:Message and MyRepeater:RepeaterRow2:Message.
A control’s UniqueID value is used heavily at runtime during the postback phase of page execution to route client data values and postback event references to appropriate server controls.
You can also utilize a server control’s ID value to obtain a reference to the control instance at runtime. Developers can search the tree for a given ID using the FindControl method exposed on the Control base class. The FindControl method will perform a relative search of the control’s naming container for the given control, and will return a reference to it if found. For example:
<html> <script language="C#" runat=server> private void Page_Load(Object sender, EventArgs e) { MyRepeater.Datasource = { "One", "Two", "Three" }; MyRepeater.Databind(); } private void ChangeBtn_Click(Object sender, EventArgs e) { HtmlGenericControl x = MyRepeater.FindControl("RepeaterRow1:Message"); if (x != null) { x.InnerHtml = "This control was found with FindControl."; } } </script> <body> <form action="Repeater.aspx" method="Post" runat=server> <asp:repeater id="MyRepeater" runat=server> <template:itemtemplate> <span id="Message" runat=server> <%# Container.DataItem %> </span> </template:itemtemplate> </asp:repeater> <input type=submit OnServerClick="ChangeBtn_Click" runat=server> </form> </body> </html>