www.gibmonks.com

Main Page

  Previous Section Next Section

3.2 Stages of Page Processing

During Web Forms processing, the page goes through distinct stages, which are illustrated in Figure 3-1. The Web Forms processor calls a corresponding page processing event at each stage.

Figure 3-1. The stages of Web Forms page processing
figs/anet2_0301.gif

In ASP pages other than global.asa, you have to write your program logic sequentially because your code is executed in the order in which it appears (termed procedural programming). ASP.NET, on the other hand, features event-driven programming, in which the order of execution of a particular code block is not predetermined. You write a block of code called an event handler that is executed whenever that event occurs.

If you've developed client-side code or have programmed using Visual Basic, you're already familiar with event-driven programming. ASP.NET takes event-driven programming to the server side, encouraging you to structure your programming logic into event handlers. In ASP.NET, the Page object is the representation of your ASP.NET page, and you can write handlers at the page level. ASP, on the other hand, supports only events at the application and session levels.

The Page class inherits all of its important events from the System.Web. UI.Control class, which is the ultimate parent of all server controls. This means that all events described below also apply to both built-in and custom server controls because all of these controls ultimately derive from System.Web.UI.Control.

We'll examine these events in detail. First, however, we'll examine how an event is associated with a particular event handler in Visual Basic .NET and C#.

3.2.1 Handling Events

There are three main techniques for handling events in ASP.NET, one of which takes advantage of ASP.NET's ability to wire up standard event handlers automatically and two of which rely on wiring up event handlers manually.

3.2.1.1 Automatic event wiring

When handling events in a page that consists of a single .aspx page, it is often simplest to create event handlers in the standard objectname_eventname syntax familiar to most Visual Basic programmers. By default, ASP.NET will automatically look for handlers such as Page_Init, Page_Load, Page_PreRender, and Page_UnLoad, and will call them automatically at the appropriate time during page processing.

While not strictly required, it's a good idea to use the objectname_eventname syntax for event handlers you write for server controls used in your page. By using a consistent standard for naming event handlers, it will be much clearer to anyone reading your code (including yourself, if you haven't looked at it in a while) which procedures are event handlers. Unlike the standard page events inherited from Control, server control events are not wired automatically. You can wire a server control event by adding an OnEventName attribute to the tag that defines the control, with the value of the attribute set to the name of the event handler, or by using one of the two methods described in the following sections.

3.2.1.2 Using AddHandler or += to wire events

One method of wiring up events to event handlers manually is to use the Visual Basic .NET AddHandler statement or the C# += operator to hook up an event to a delegate. Delegates, which are used to create event handlers, are similar to function pointers, but are type-safe. The following code snippets illustrate hooking up an event handler for the Click event of an ASP.NET Button server control named Button1:

// C#
Button1.Click += new System.EventHandler(Button1_Click);
  
' Visual Basic .NET
AddHandler Button1.Click AddressOf Button1_Click

In both cases, the code tells ASP.NET where to find the procedure to execute when the Click event (namely, Button1.Click) is fired. If, for some reason, you want to unwire an event handler, you can use the Visual Basic .NET RemoveHandler statement or the C# -= operator to accomplish the reverse of AddHandler and +=.

3.2.1.3 Using the WithEvents and Handles keywords to wire events

Visual Basic .NET developers have a third option for wiring up events: the WithEvents and Handles keywords. The WithEvents keyword precedes the name of a declared control (usually in a code-behind class) and tells ASP.NET that you want to be able to handle the control's events using the Handles keyword. The Handles keyword is appended to the first line of the event handler procedure and is followed by the object name and the name of the event it handles. The syntax of these keywords is shown in the following code snippet. Note the use of the VB line continuation character, which indicates that both the Sub declaration and the Handles keyword should be interpreted as a single line of code:

Protected WithEvents MyButton As New Button
  
Private Sub MyButton_Click(sender As Object, e As EventArgs) _
   Handles MyButton.Click
   'Event handling code
End Sub

When using the AddHandler, +=, or WithEvents/Handles techniques for wiring up the standard events (Init, Load, etc.) manually, you should add the AutoEventWireup attribute to your page's @ Page directive, with the value set to False. Otherwise, the event handlers will be called more than once. Fortunately, new pages added to a web project in Visual Studio .NET have this attribute set to False by default.

3.2.2 ASP.NET Page and Control Events

Each stage of Web Forms processing shown in Figure 3-1 exposes particular events that can be handled in your code. In this section, we'll examine those events in detail.

3.2.2.1 Init

The Init event, which is fired with each request, is used to initialize the page. If variables need to be declared and initialized before the majority of page processing begins, the event handler for the Init event is the place to do it. A good example of this is that for C# web projects in Visual Studio .NET, the Page_Init event handler is used to wire up other events handled by a page's code-behind class. The Page_Init handler, in turn, is wired up in the constructor for the code-behind class.

It's important to ensure that the logic performed in the Init event handler is the same for each request to the page, particularly with respect to adding controls to the control tree. Not following this recommendation can lead to problems when posting back to the page.

3.2.2.2 Load

The Load event is fired on every request to the page, immediately after all the controls on the page have been initialized. Since this event is fired every time the page is loaded, and if your page is posted to itself (known as a postback), you can use the IsPostBack property of the Page object to write logic that executes only once. For instance, in the code in Example 3-6, you will see the label "Before PostBack" the first time you load the page because, since the page has not been submitted to itself yet, the IsPostBack property is False. When the page is posted back, you will see the label "Posted Back" because the IsPostBack property has become True.

Example 3-6. An ASP.NET page using the PostBack property
<%@ Page Language="vb" %>
<html>
<head>
<title>IsPostBack Demonstration</title>
<script runat="server" >
   Sub Page_Load(Sender As Object, e As EventArgs)
      If Not IsPostBack Then
         lblMessage.Text = "Before PostBack" 
      Else
         lblMessage.Text = "Posted Back" 
      End If
   End Sub
</script>
</head>
<body> 
   <h1>Demonstration of IsPostBack property</h1>
   <form id="frmPostBack" runat="server">
      <asp:label id="lblMessage" runat="server"/>
     <asp:Button type="Submit" text="Post Back" runat="server"/>
   </form>
</body>
</html>
3.2.2.3 DataBinding

The DataBinding event is fired when the page (or a control) is bound to a data source. This will usually occur when the DataBind method of the Page object is called, generally from the Page_Load event handler. The DataBinding event handler can be used to do any special processing related to the data-binding portion of page processing. Databinding is covered in greater detail in Chapter 7.

3.2.2.4 Control events

Server control events are used primarily in an ASP.NET page to write the UI and programming logic of that page. Control events can be categorized broadly as either change events or action events.

The control event handlers are identified by an attribute of the control's tag. For example, in the following tag:

<asp:Button id="MyButton" onClick="MyButton_Clicked" runat="server">

the attribute/value pair onClick="MyButton_Clicked" connects the control event (the Click event) with its event handler (the MyButton_ Clicked procedure).

Change events execute only on the next request to the server. For example, if you have written an event handler for the TextBox_Changed event, only when the page is submitted to the server will the code inside the handler be executed. Server-side change events are not the same as the client-side change events that execute instantly.

The most commonly used Change events and the controls that raise these events are listed in Table 3-1.

Table 3-1. Change events

Event

Description

Controls

OnAdCreated

Raised after creation of the control and immediately before the page is rendered. If an Advertisement file is provided, OnAdCreated is raised after an ad has been selected from the file.

AdRotator

OnDayRender

Raised as each cell is created.

Calendar

OnVisibleMonthChanged

Raised when the user clicks a button for the next or previous month in the Calendar's title.

Calendar

OnSelectionChanged

Raised when the user selects a day, week, or month selector.

Calendar

List

OnSelectedIndexChanged

Raised when the user changes the selection.

CheckBoxList

DropDownList

ListBox

RadioButtonList

OnCheckedChanged

Raised when the user clicks the control.

CheckBox

RadioButton

OnPageIndexChanged

Raised when the user clicks a page selection element.

DataGrid

Action events, unlike Change events, immediately cause the page to be posted back to the server. For example, if you have an event handler for the Command_Click event, the logic inside the handler will be executed as soon as you click that command button (after the page is posted back to the server, of course).

The most commonly used Action events and the controls that raise them are listed in Table 3-2.

Table 3-2. Action events

Event

Description

Controls

OnClick

Raised when the user clicks the control.

Button

ImageButton

LinkButton

OnCommand

Used to pass the CommandEventArgs argument which allows data about which command should be executed, based on the CommandArgument and/or CommandName properties of the control.

Button

ImageButton

LinkButton

OnCancelCommand

Raised by a control whose Command property is Cancel. Typically, this Button or LinkButton control is declared in the EditItemTemplate.

DataGrid

DataList

OnDeleteCommand

Raised by a control whose Command property is Delete. Typically, this Button or LinkButton control is declared in the ItemTemplate.

DataGrid

DataList

OnEditCommand

Raised by a control whose Command property is Edit. Typically, this Button or LinkButton control is declared in the ItemTemplate.

DataGrid

DataList

OnItemCommand

Raised in the control when an embedded control raises an event that is not already covered by Edit, Cancel, Delete, or Update.

DataGrid

DataList

OnUpdateCommand

Raised by a control whose Command property is Update. Typically, this Button or LinkButton control is declared in the EditItemTemplate.

DataGrid

DataList

OnItemCreated

Raised on the server each time a control is created.

DataGrid

DataList

OnSortCommand

Raised when a column is sorted.

DataGrid

3.2.2.5 PreRender

The PreRender event is fired just before the page (or control) is rendered and sent to the client. The PreRender event is the last chance for page output to be modified before it is sent to the browser. It is also the last event that fires before the ViewState of the controls on the page is saved, so any control changes you wish to have saved to ViewState should be made either before or during this event. ViewState is discussed more fully in the Section 3.3 in this chapter. The PreRender event is also the last opportunity for registering client-side script blocks using the helper methods of the Page class (such as Page.RegisterClientScriptBlock).

3.2.2.6 Unload

The Page_Unload event is fired after the page is rendered. You can use the Page_Unload event handler to write cleanup code.

For example, in the following snippet, the database connection objConnection is closed:

Sub Page_Unload(sender As Object, e As EventArgs )
    ' Close the database connection
    objConnection.Close( )
End Sub
      Previous Section Next Section