As discussed earlier, at runtime ASP.NET combines the code in the page and any associated code-behind class into a single class, and then it compiles that class and executes it on the server. In the process, ASP.NET builds a control tree containing all of the controls on the page, including LiteralControl server controls for each section of HTML text.
When compiling a page, ASP.NET automatically creates controls that represent the HTML markup in the page, using the LiteralControl server control class. This allows you to easily manipulate the HTML markup at runtime, and also allows greater flexibility in adding controls at runtime. If the page contains <% %> render blocks, however, ASP.NET will not create controls to encapsulate the HTML markup. If you want to be able to manipulate the markup as LiteralControls, don’t use <% %> render blocks.
At the top of the control tree is the control that represents the page, which has the ID __PAGE. Beneath that control are any child controls that belong to the page’s Controls collection. Each child control, depending on the type of control, can in turn have its own Controls collection containing child controls, and so on. This structure makes it much easier to find and manipulate controls at runtime.
The easiest way to view the control tree for a page is to turn on tracing for the page.
Open ServerControls.aspx in a text editor.
Add the Trace attribute to the @ Page directive and set its value to true. The completed directive is as follows:
<%@ Page Language="cs" Trace="true" %>
Save the file and browse the page. The control tree section of the CompoundContainer.aspx trace output is shown in the illustration on the next page. Notice that where a control has been given an explicit ID through its id tag attribute, that ID is used in the control tree.
Thanks to the control tree built by ASP.NET at runtime, you can easily add, remove, or manipulate controls at runtime, even if you don’t know the name of a control. For example, you can use the Add method of the page’s Controls collection to add a new control to the page at runtime:
TextBox MyTextBox = new TextBox() Page.Controls.Add(MyTextBox);
If you want to place the new control at a particular position in the control tree, you can use the AddAt method instead:
TextBox MyTextBox = new TextBox() Page.Controls.AddAt(2, MyTextBox);
To remove a control by name, you can use the Remove method:
To remove a control by index, you can use RemoveAt:
To locate a particular control by ID, you can use the FindControl method of the page or control containing the control you’re looking for:
Note that because FindControl returns an object of type Control (rather than of the specific type of control found), you will need to cast to the appropriate control type before using properties or methods that are specific to that control type.