How to: Add Controls to an ASP.NET Web Page Programmatically
At times it is more practical to create a control at run time than at design time. For example, imagine a search results page in which you want to display results in a table. Because you do not know how many items will be returned, you want to dynamically generate one table row for each returned item.
Note |
|---|
| Existing controls can often provide the functionality you get from creating controls dynamically. For example, controls such as the Repeater, DataList, and RadioButtonList controls can dynamically create rows or other control elements when the page runs. |
In order to programmatically add a control to a page, there must be a container for the new control. For example, if you are creating table rows, the container is the table. If there is no obvious control to act as container, you can use a PlaceHolder or Panel Web server control.
In some instances, you might want to create both static text and controls. To create static text, you can use either a Literal or a Label Web server control. You can then add these controls to the container as you would any other control. For information about view state in controls created at run time, see Dynamic Web Server Controls and View State.
Important |
|---|
To add a control to an ASP.NET Web page programmatically
-
Create an instance of the control and set its properties, as shown in the following example:
Note Controls are typically added to the page during the page's initialization stage. For details about page stages, see ASP.NET Page Life Cycle Overview.
-
Add the new control to the Controls collection of a container already on the page, as shown in the following example:
Note Because the Controls property is a collection, you can use the AddAt method to place the new control at a specific location — for example, in front of other controls. However, this can introduce errors into the page. For details, see Dynamic Web Server Controls and View State.
The following code example shows the event handler for the SelectedIndexChanged event of a control named DropDownList1. The handler creates as many label controls as the user has selected from the drop-down list. The container for the controls is a PlaceHolder Web server control named Placeholder1.
Security Note User input in a Web page can include potentially malicious client script. By default, ASP.NET Web pages validate that user input does not include script or HTML elements. For more information, Script Exploits Overview.
private void DropDownList1_SelectedIndexChanged(object sender, System.EventArgs e) { DropDownList DropDownList1 = new DropDownList(); PlaceHolder PlaceHolder1 = new PlaceHolder(); // Get the number of labels to create. int numlabels = System.Convert.ToInt32(DropDownList1.SelectedItem.Text); for (int i=1; i<=numlabels; i++) { Label myLabel = new Label(); // Set the label's Text and ID properties. myLabel.Text = "Label" + i.ToString(); myLabel.ID = "Label" + i.ToString(); PlaceHolder1.Controls.Add(myLabel); // Add a spacer in the form of an HTML <br /> element. PlaceHolder1.Controls.Add(new LiteralControl("<br />")); } }
See Also
(This is divided into two pieces due to length constaints.)
o override LoadViewState, you can do something like this:
Protected Overrides Sub LoadViewState(ByVal savedState As Object)
MyBase.LoadViewState(savedState)
If Me.ControlsAdded Then
Me.AddControls()
End If
End Sub
This block relies on two additional techniques. One is a helper method (AddControls, not shown here) that contains the code to add the control(s) you want to add dynamically. As part of that code, you set a page property (Me.ControlsAdded=True) that acts as a flag indicating that the controls have been added, so that on the next postback, your code will know to recreate them.
The code for the page property might look like this:
Private Property ControlsAdded() As Boolean
Get
If ViewState("ControlsAdded") Is Nothing Then
Return False
Else
Return True
End If
End Get
Set(ByVal Value As Boolean)
ViewState("ControlsAdded") = Value
End Set
End Property
Note that the property value is stored in viewstate so that is survives a postback. (Simply setting a global variable doesn't work, because the page is discarded after it has rendered.)
(This is divided into two pieces due to length constaints.)
One of the most confusing aspects of creating controls dynamically is that you have to recreate them after postback -- the entire page is recreated on each postback, and although ASP.NET can recreate the controls from the declarative syntax on the page, it doesn't know about any controls that you've added programmatically.
To add to the confusion, the controls you have added often have some viewstate (ie, they have non-default property settings). Toward the end of the the page life cycle (http://msdn2.microsoft.com/en-us/library/ms178472.aspx), the page asks each control for any values to contribute to viewstate (this includes your dynamically-added controls); the information is added to the viewstate tree and stored in the page in a hidden field (http://msdn2.microsoft.com/en-us/ms178198.aspx). When the page is recreated, at an early stage ASP.NET recreates the controls it knows about and matches up viewstate with the controls, which resets the controls' property values to what they were at the last rendering.
When you are working with dynamic controls, then, not only do you have to recreate them on each postback, but you have to do so at a point in page processing that occurs before viewstate is parsed and reset for each control. You must do this before the page's Load event. You can do it in Page_Init. Another way to do it is to override the LoadViewState method. (See next entry.)