« XmlSerializer ctor failure in ASP.NET context | Main | Troubleshooting ASP.NET authentication, authorization, and security issues »

ViewState, LoadViewState, and dynamically added UserControls

Dynamically adding UserControls (ascx files and classes derived from System.Web.UI.UserControl) gets tricky when you start needing the controls re-instantiated at postback time.

For this discussion, I start with a conventional Web Form page (aspx file and class derived from System.Web.UI.Page) where the Page_Load method contains logic to create and add a variety of System.Web.UI.Control derived instances to the page’s Controls collection. The Page_Load implementation should only do the construction if IsPostPack is false because the context that determines how many and/or which controls to create should come from the ViewState for a post back.

Here are a few things to keep in mind:

1.      LoadViewState gets called before Page_Load and only on post back (i.e. when the request contains a hidden __VIEWSTATE form field.)

2.      If the correct structure of controls exists at the end of the Page derived class’ LoadViewState method then their state will automatically be restored.

3.      The content of the savedState argument to LoadViewState is just the state for the current control. It does not include the state for child controls.

4.      The Page class’ LoadViewState implementation restores any ViewState[string] assignments that were made.

 

A simple way to have the state of dynamically created controls restored on post back is to do the following:

1.      At the end of the Page_Load implementation, store just enough information in ViewState to recreate the same structure on post back. E.g. ViewState[“DynamicControlCount”] = 6;

2.      Override the LoadViewState method in the derived Page class.

a.       First call base.LoadViewState(savedState). This will restore the page’s ViewState. E.g. the value of ViewState[“DynamicControlCount”].

b.      Use ViewState[“DynamicControlCount”] to recreate the prior control structure.

 

That’s it! After calling the derived page class’ LoadViewState method, the framework will call the LoadViewState methods on each child control in a fixed traversal order.

 

Post a comment

(If you haven't left a comment here before, you may need to be approved by the site owner before your comment will appear. Until then, it won't appear on the entry. Thanks for waiting.)