|Important||This document may not represent best practices for current development, links to downloads and other resources may no longer be valid. Current recommended version can be found here.|
Web Forms Control Identification
Every control on an ASP.NET Web page must be uniquely identifiable. Generally, you assign a value to a control's ID property to uniquely identify it. This value becomes the instance name of the control — that is, the name by which you can refer to the control in code. For example, if you set the ID property of a TextBox control to Text1, you can reference the control in code as Text1.
A number of data-bound controls, including the DataList, Repeater, GridView, FormView, and DetailsView controls, act as containers for other (child) controls. When these controls run, they generate multiple instances of the child control. For example, if you create a DataList template with a Label control in it, when the page runs, there are as many instances of that Label control in the page as there are records in the DataList control's data source.
Controls that use templates, such as the DataList and Repeater controls, host template objects. For example, when the DataList control runs, it creates multiple instances of the DataListItem class. These template objects in turn contain individual controls such as labels, text boxes, buttons, and so on.
Because controls can be instantiated multiple times on the same page, and because you can reuse control names on different pages, the ASP.NET page framework provides mechanisms to ensure that controls on the page and in your application have unique identifiers. It also provides you with ways to find these individual controls so that you can manipulate them in your own code.
Controls that can act as containers for other controls generate a naming container, or an ID namespace, for their child controls. By providing this naming container, controls can guarantee that ID attributes of their child controls are unique within the entire application. (Controls generate a naming container by implementing the INamingContainer interface.) When child controls are created at run time, the naming container is combined with the child control's ID property to create the value of the UniqueID property of each child control. The UniqueID property therefore becomes a fully qualified identifier for a control, referencing its naming container as well the controls' individual ID value.
In the example from above, the multiple instances of the Label control are created within the naming container — the namespace — of the parent DataList control. The UniqueID property of each Label control will reflect this namespace, which will have a format something like DataList1:_ctl:MyLabel, DataList1:_ct2:MyLabel, and so on.
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.
In addition to each container control providing a naming container for its child controls, the page itself also provides a naming container for all of its child controls. This creates a unique namespace within the application for all the controls on that page.
Child controls can reference their naming container via the NamingContainer property. This property returns an object of type Control that you can cast to the appropriate DataList control, DataListItem object, and so on.
Referencing the naming container is useful when you need access from a child control to a property of the container control. For example, in a handler for a child control's DataBinding event, you can access the DataItem object by getting it from the naming container.
The NamingContainer property does not necessarily reference the same control as the Parent property. For example, in a Repeater control, you might have an item template containing a table that in turn contains a Label control. The parent control of the label is a table cell (for example, a HtmlTableCell object), but its naming container is the DataListItem object, because it is the DataListItem that defines the namespace for the Label control, not the table.
If your page contains controls that are generated at run time, such as those in a template for the DataList, Repeater, or GridView controls, you cannot directly reference them by their ID, because the ID is not unique. However, there are various ways to find individual controls in the page. For details, see Accessing ASP.NET Controls Programmatically.