views:

361

answers:

3

I am pretty sure back in the days of ASP.NET 1.0/1.1, controls created during runtime needs to be added before Page_Load event of the Page Lifecycle (i.e. inside Page_Init).

Here's one article by Microsoft on it (for .NET 1.0/1.1):
HOW TO: Dynamically Create Controls in ASP.NET:

Note When you create dynamic controls on a Web Form, you must create the controls and add them to the controls collection in either the Page_Init event handler or the Page_Load event handler. Otherwise, the controls may not behave as expected.

However, in a few posts here, it seems like the above is not the case anymore. Controls added within Page_Load seems to be working for everyone else. Some of the posts include:
http://stackoverflow.com/questions/886664/creating-dynamic-control-in-asp-net
http://stackoverflow.com/questions/1708016/viewstate-utter-confusion

I've tried it myself and indeed it worked though I've not done enough test to fish out any unexpected behavior.

So is Page_Load a safe stage to add dynamic controls? Or is it only for .NET 2.0 and above?

+2  A: 

You can add controls at any time. However, they'll only work with viewstate if you add them before page loads.

In fact, if you check the .Net 2.0 version of the page lifecycle link you posted, you'll stilll find this quote under the PreInit event:

Use this event for the following: ... Create or re-create dynamic controls.

Joel Coehoorn
@Joel: Good catch! So does it mean as much as possible, we should always create dynamic controls in PreInit?
o.k.w
Yes. Obviously controls created in response to, say, a button press need to be created elsewhere. But when _re-creating_ controls for postbacks, PreInit is absolutely the correct place to do it.
Joel Coehoorn
@O.K.W, we can override CreateChildControls and can create control in this event as well..
Muhammad Akhtar
"they'll only work with viewstate if you add them before page loads."They work in page_load too.
maxp
@Muhammad: Thanks for the pointer :)
o.k.w
@maxp: Glad you jump over here from the your question. I'm really curious about this healthy 'debate' :P
o.k.w
+1  A: 

The Page_Load event handler is an acceptable place to add controls. If you re-read your note you will notice that they state that.

Note: When you create dynamic controls on a Web Form, you must create the controls and add them to the controls collection in either the Page_Init event handler or the Page_Load event handler. Otherwise, the controls may not behave as expected.

If the ASP.NET 2.0 article you linked to, under "Catch-up Events for Added Controls", they discuss how added controls are brought up to speed with the page.

Mike J
@Mike: Gosh, I missed that. I guess I chose to digest what I believe. Thanks for highlighting. But Joel's answer gives a different light.
o.k.w
+2  A: 

I have studied this with Reflector, and the Control class does indeed bring things up to speed when you add them dynamically, no matter when you add them. It does everything - loads viewstate/controlstate, calls postback events, calls event handlers, etc. I don't know if it was different in ASP.NET 1.x days, but in 2.0 and above this is the case.

As for the "dangers" - there are some gotchas that the inexperienced user might trip over, so it is recommended that you add them in Page_Init or before. (Note that the PreInit event only applies to the page itself, not the Master Page or subcontrols). Off the top of my head (I'm sure there might be a few more):

  • By default viewstate loads positionally. That is, it ignores control IDs and just takes control placement in the tree into account when loading viewstate. If your dynamic controls were present when the viewstate was serialized, but are not present when it is deserialized, the wrong viewstate item might get assigned to the wrong control, thus leading to exceptions. This can be changed by some settings, though I'm now too lazy to search for them.
  • Since the "bringing up to speed" happens when the dynamic control gets added to the page, the order of some events might be unexpected. For example, if you add a TextBox control to the page in the Page_PreRender event, the Changed event of the TextBox will happen there and then. If your event handler code depends on the event happening with the rest of them before PreRender, then you are screwed.
Vilx-
@Vilx-: Your post is one of more comprehensive ones I've read regarding to this issue. :)
o.k.w
I'm dealing with dynamically added controls on a regular basis, so I had to understand this. :)
Vilx-