Dynamically Loaded Control can not maintain values at PostBack?

I was trying to create and page with Asp.NET 2.0 and Ajax 1.0.

I was using a placeholder control to dynamically load a user control based on the user selection.

The first error I encountered is :

{"Failed to load viewstate.  The control tree into which viewstate is being loaded must match the control tree

that was used to save viewstate during the previous request.  For example, when adding controls dynamically, the

controls added during a post-back must match the type and position of the controls added during the initial

request."}

This is because I'm suppose to load the same user control on every page request, not only in (!IsPostBack) block. I solved that by moving the loading code to Page's OnInit event handler. According to MSDN article, http://msdn2.microsoft.com/en-us/library/ms972976.aspx#viewstate_topic4, here is the time when the page can load all of it's child controls before restore their viewstates.

After that, everything looks fine except that I can't get the value I entered into the dynamically loaded user control when post back! To make it more interesting, when keep the same user control loaded (don't load other user controls), I enter the value again, and click submit again, boom! You got it.

What could be wrong? After a day of scratching head and debugging, I notice that every time I load a different control, the loaded user control's ID is randomly assigned such as 'ctl26'. So I explicitly specify the ID before load it:

Control ctl = LoadControl(ControlPath);

ctl.ID = "UcSecuritySubTypeDetails";

placeHolderSecuritySubTypeDetails.Controls.Add(ctl);

Now everything works together. So the keys of using dynamically loaded control is:

1. Load it every time.

2. Give it an explicit ID

One thing I need to clarify is that initially I was loading the dynamic control in Page_PreInit event handler as suggested by the MSDN article: http://msdn2.microsoft.com/en-us/library/ms178472(VS.80).aspx. It says PreInit event is typically used for "Create or re-create dynamic controls". But if do as such, I will get an error complaining that the object of my placeholder control is not yet instantiated.  That is because although Page is derived from Control class, but at Page_PreInit stage of the Asp.NET life cycle, only Page object is created, all sub-controls include the placeholder are initiated after Page_PreInit and before Page_Init. Check Alex Arkhipov's nice post here for details of Asp.NET 2.0 Page life cycle:
http://blogs.vertigosoftware.com/alexark/archive/2005/05/06/898.aspx

Page_Init is the best place you can load the dynamic controls into a parent control other than the Page.

This article is part of the GWB Archives. Original Author: Chris Han

New on Geeks with Blogs

  • We Won The One Award I Actually Care About

    Full Scale made the Inc. 5000 for the fifth year straight, the 12th listing across my three companies. Here is why the one award you cannot buy is worth stopping for.

  • Your Customers Build the Features Now

    I let a tool I liked sit dead for a year rather than build the features I wanted. An MCP server meant I never had to, and your customers can do the same to your product.

  • Get the Size of a Directory in Linux the Easy Way

    du -sh for the quick answer, ncdu for the cleanup, df for the disk itself: every command for checking directory size in Linux, plus why du and df never agree.

  • Vim Search and Replace: The Ultimate Guide

    One :%s command replaces every match in a file before a find dialog would even open. The Vim substitute patterns worth the muscle memory: flags, ranges, capture groups, and multi-file edits.