Understanding the Page Life Cycle

Before you can appreciate how dynamic and static controls work within the framework of a Page object, you must first understand the life cycle of a web page. When users post back a web page, they normally do so via a button or link object. This object may have JavaScript code attached to it which may contain some validation routines. There's no point in even attempting an expensive full-page postback unless the data being posted back is valid. Then, a series of postback events trigger, most of which you never need to worry about. The following list contains this series of postback events:

• Prelnit: You can instantiate user controls in the Prelnit method if you wish. You can also set properties of static controls. However, this only applies to pages that don't have master pages. If they do, the static controls aren't available at this stage. The reason is that all controls placed in the content page are within the master page's ContentPlaceholder. When the master page merges with the content pages, all events except Init and Unload are triggered from the outermost to the innermost control. Therefore, the Prelnit event in the content page fires first. User controls and, by extension, a master page, which is itself is treated as a user control, don't possess a Prelnit event. Therefore, in the Page_PreInit event, neither the master page nor any user control has been instantiated, and only the controls inside the content page are set to their default values. In general, you would do better to instantiate your dynamic controls in the Init event. But you must use Prelnit to assign themes and skins.

• Init: At this point, every control has been instantiated. Each control has its own Init event that also fires. This (or the Load event) is the spot to set control properties.

• InitComplete: At this point, the controls are instantiated, but their attributes aren't yet populated from the ViewState.

• LoadComplete. Here you can execute code that requires all controls on the Page object to be both instantiated and initialized, either by you or from the ViewState.

• PreRenderComplete

When the Page is posted back to the server, it begins its process of rebirth anew. First, the Page object is instantiated; the controls defined with it are instantiated as well. After this is accomplished, the controls' properties are initialized from the ViewState to reset the values and attributes they held before the postback. Next, the postback data is restored. The Page_Init method fires at this point. Next, the Page_Load event fires. After this is completed, the web page is rendered—the PreRender event fires— and the page is returned to the web client.

It's important to understand the Page life cycle because the sequence of events directly affects your ability to use dynamic controls. First, it's important to understand that dynamic controls don't persist between postbacks and must be re-created every time the page posts back. This means your routine to instantiate these controls can't be invoked from with an if (! Page. IsPostback) construct.

The code in Listing 5-4 shows the firing sequence of the page and control events for a page that has one Button control on it.

Listing 5-4. Page and Control Events public partial class _Default : System.Web.UI.Page {

protected void Page_PreLoad(object sender, EventArgs e) Response.Write("Fire Page_PreLoad" + "<BR>");

protected void Page_Load(object sender, EventArgs e) Response.Write("Fire Page_Load" + "<BR>");

protected void Page_LoadComplete(object sender, EventArgs e) Response.Write("Fire Page_LoadComplete" + "<BR>");

protected void Page_PreInit(object sender, EventArgs e)

Response.Write("Fire Page_PreInit" + "<BR>");

Buttonl.Init += new EventHandler(this.Button1_Init); Buttonl.Load += new EventHandler(this.Button1_Load); Button1.PreRender += new EventHandler(this.Button1_PreRender); Button1.Unload += new EventHandler(this.Button1_Unload);

protected void Page_Init(object sender, EventArgs e) Response.Write("Fire Page_Init" + "<BR>");

protected void Page_InitComplete(object sender, EventArgs e) Response.Write("Fire Page_InitComplete" + "<BR>");

protected void Page_PreRender(object sender, EventArgs e) Response.Write("Fire Page_PreRender" + "<BR>");

protected void Page_PreRenderComplete(object sender, EventArgs e) Response.Write("Fire Page_PreRenderComplete" + "<BR>");

protected void Page_Unload(object sender, EventArgs e) // Fires last after all other events;

protected void Button1_Unload(object sender, EventArgs e) // Fires after all other events except Page_Unload;

protected void Button1_Load(object sender, EventArgs e) Response.Write("Fire Button1_Load" + "<BR>");

protected void Button1_Init(object sender, EventArgs e) Response.Write("Fire Button1_Init" + "<BR>");

protected void Button1_PreRender(object sender, EventArgs e) Response.Write("Fire Button1_PreRender" + "<BR>");

protected void Button1_Click(object sender, EventArgs e) Response.Write("Fire Button1_Click" + "<BR>");

When this code is executed, you see the web page shown in Figure 5-3. The Unload events can't write to the page because by then it's too late to use Response.Write. These are the last events fired in the sequence.

^lSjxj

File Edit View History Bookmarks Tools Help

C AJ J L_ http : //localhost : 3185/Chapter - ||G]

'1 Guogle

Möst Visited & Getting Started Latest Headlines • http://code.msdn.mic

Jl * -

Fire Page_PreImt

Fire Button 1 Imt

Fire Page_Imt

Fire Page_InitComplete

Fire Page_PreLoad

Fire Page_Load

Fire Button 1 Load

Fire Page_LoadComplete

Fire Page_PreRender

Fire Button 1 PreRender

Fire Page_PreRenderComplete

Button |

Dane

Figure 5-3. Firing page and static control events

If the static button control is dynamically instantiated as shown in Listing 5-5, you get the same results as shown in Figure 5-4. All the controls exist at the same time, and the events fire in the same sequence.

^lSjxj

File Edit View History Bookmarks Tools Help

C AJ J L_ http : //localhost : 3185/Chapter - ||G]

'1 Guogle

Most Visited ^ Getting Started Latest Headlines • http://code.msdn.mic

Jl * '

Fire Page_PreImt

Fire Button 1 Imt

Fire Page_Imt

Fire Page_InitComplete

Fire Page_PreLoad

Fire Page_Load

Fire Button 1 Load

Fire Page_LoadComplete

Fire Page_PreRender

Fire Button 1 PreRender

Fire Page_PreRenderComplete

Button |

Dane

Figure 5-4. Firing page and dynamically instantiated control events Listing 5-5. Wiring Event Handlers protected void Page_Init(object sender, EventArgs e) {

Response.Write("Fire Page_PreInit" + "<BR>");

Button oButton = new Button(); oButton.Text = "Button";

oButton.Init += new EventHandler(this.Button1_Init); oButton.Load += new EventHandler(this.Button1_Load);

oButton.PreRender += new EventHandler(this.Button1_PreRender); oButton.Unload += new EventHandler(this.Button1_Unload);

PlaceHolderl.Controls.Add(oButton);

0 0

Post a comment