Introduction
The principle of loading web user controls dynamically is easy, that is to use the PlaceHolder
control. However, it is not easy to make dynamically loaded controls to work properly if we miss some key points. Detailed information about how to use web user controls dynamically is introduced in this article.
Problem Description
Firstly, remember to use the LoadControl
method instead of just creating a new instance of the web user control. Using the new
operator to create the instance of the web user control won't work because it just creates the control itself. All the child controls in the created web user control won't be initialized, as we can see in the following figure:
In the example above, the HelloWorld
web user control contains a button (btnSayHello
), a label (lblHello
), a required field validator (rfv
), and a text box (txtName
). We can see that after HelloWorld
has been created, no control within it is initialized.
So use the Page.LoadControl
method instead of the new
operator. The following figure shows the value of the members in the created control, which is much different from the ones we got previously.
After getting the control instance that is returned by the Page.LoadControl
method, we can now use the PlaceHolder
to render the control. The following line shows how:
PlaceHolder1.Controls.Add(control);
Now you can render the control properly on the page. But what's next? When you want to fire server events in your loaded web user control, you'll find that everything is gone! The control totally disappears when the page is posted back.
What happens? Actually, ASP.NET pages run in the server environment, and it is a stateless object. This means once the page is generated for the client, the instance is disposed. So if we define a local variable in the page object, we cannot get its pervious value when the page is posted back because the page object is pretty new other than the one we first worked with.
In order to correctly render the control even if the page is posted back from the server, we must persist the control so that it can be re-rendered when the page is initializing or loading. It is impossible to persist the entire web user control with the view state or session because the web user control is not serializable. We can persist the virtual path of the control instead, so that the control can be recreated once the proper page events are fired. Don't worry about the state of the fields within the control, they will be maintained by the control itself.
Solution
Now we have the steps for loading and using web user controls dynamically. We can follow these steps which are briefly described below (for detailed solutions, please refer to the attached source files).
- Implement a private property for saving and retrieving the saved virtual path of the web user controls.
- Implement a private method for creating and loading the web user control according to the saved virtual path. It is important to remember to set the ID for the control; otherwise, the page won't work properly.
- In
Page_Load
event, simply call the method we created in step 2 to recreate the control. - In the
Button_Click
event, set the private property we created in step 1 to the virtual path of the control that needs to be created and loaded; then call the method we created in step 2 to recreate and load the control. - Override the
Dispose
method and dispose the controls.