Rob Garrett - Blogs

Welcome to Rob Garrett - Blogs Sign in | Join | Help
in Search
Google

Software/Technology Discussion

Software and Technology Tid-bits

Event catch-up in ASP.NET 2.0 Controls

Pop quiz, what is wrong with the following class?


The class above is a custom server control that derives from an ASP.NET PlaceHolder control.  This example is a stripped down version of a class I am currently working on this week (which loads controls dynamically from custom XML).  I chose the PlaceHolder control to derive from because I needed a container control, in which to hold my dynamically instantiated controls - the PlaceHolder control is designed for, and ideal for this purpose.

I ran into a problem with persistence of property values belonging to dynamic controls when contained in my custom MyPlaceHolder control.  In the above example I have created a DropDownList control dynamically in the OnPreRender method, and added it to the controls collection of MyPlaceHolder, which, as it turns out is a problem.....

Those of you who know enough about how ASP.NET works (1.1 and 2.0), will know about "catch-up":

When controls are declared statically in an ASPX page, ASP.NET instantiates these controls, adds them to an in-memory control tree, and then calls various event methods on each control, and child controls recursively, before the page is rendered.  (I have included the order of events of all controls in ASP.NET later in this post).

When a control is created dynamically, the time in which the control is instantiated is at the mercy of the developer. For this reason, ASP.NET plays "catch-up" and arranges to call all missed event methods so that the control is in sync with it's container. Using the above code as an example - after instantiating the drop down list control and adding this control to the controls collection of the placeholder, ASP.NET will call the OnInit, LoadViewState, and OnLoad event methods of the drop down list control, after which the drop down list control will have caught up to the pre-render event of the placeholder container.

So, why do I loose persistence of property values in my drop down list control, specifically the selected index property? 

When ASP.NET plays "catch up", the framework will call some, or all of the OnInit, LoadViewState, OnLoad, and OnPreRender methods, depending on the current state of the containing control.  The methods to process post back data are not called during catch-up.

The following AddedControl method exists as part of the Control class in the ASP.NET 2.0 framework (version 1.1 will have similar code), and demonstrates "catch-up", using the current state of the control. Notice that no call exists to load post data.


My drop down list box  looses persistence because, by the time the control is instantiated at the pre-render stage, the time for loading post back data has passed. 

Loading of post back data is in fact performed by the Page class in the ProcessPostData method, which is called twice by the ProcessRequestMain method - once before the OnLoad method (before OnPreLoad in ASP.NET 2.0), and again (if not called prior) just after the OnLoad method completes. This loading of post data before and after OnLoad allows the developer to add dynamic control instantiation code in the most derived version of OnLoad method without having to worry about when the base version is called.

More details about event "catch-up" can be on this excellent post. Also, check out the Page.ProcessRequestMain, Page.ProcessPostData and Control.AddedControl methods in the framework using Lutz Roeder's Reflector.

As promised earlier, here is a list of the event methods called by ASP.NET 2.0 in a page render life cycle:

Page Life cycle methods in ASP.NET 2.0

Method Active
Constructor Always
Construct Always
TestDeviceFilter Always
AddParsedSubObject Always
DeterminePostBackMode Always
OnPreInit Always
LoadPersonalizationData Always
InitializeThemes Always
OnInit Always
ApplyControlSkin Always
ApplyPersonalization Always
OnInitComplete Always
LoadPageStateFromPersistenceMedium PostBack
LoadControlState PostBack
LoadViewState PostBack
ProcessPostData1 PostBack
OnPreLoad Always
OnLoad Always
ProcessPostData2 PostBack
RaiseChangedEvents PostBack
RaisePostBackEvent PostBack
OnLoadComplete Always
OnPreRender Always
OnPreRenderComplete Always
SavePersonalizationData Always
SaveControlState Always
SaveViewState Always
SavePageStateToPersistenceMedium Always
Render Always
OnUnload Always
Share this post: Email it! | bookmark it! | digg it! | reddit!
Published Thursday, August 18, 2005 11:58 PM by Rob Garrett

Comment Notification

If you would like to receive an email when updates are made to this post, please register here

Subscribe to this post's comments using RSS

Comments

No Comments

Leave a Comment

(required) 
(optional)
(required) 
Submit

Blurb


Head Shot
Rob Garrett is a British Expat living in Maryland USA. Rob is a trained software engineer and experienced in Windows .NET development.

Rob enjoys listening to Rock music, posting to blogs, driving in the country with the sunroof open, beer (not in conjunction with country driving) and spending time with his family.

This Blog

Syndication

Powered by Community Server, by Telligent Systems