webdeveloper.earthweb.com/webjs/article.php/982451

Back to Article

Web Forms: The Web Forms Programming Model
By Jeff Prosise
February 27, 2002

Page-Level Events

Server controls that render HTML and fire events are a cornerstone of the Web Forms programming model, but controls aren't the only entities that fire events. Pages do, too. To understand page-level events, it helps to understand what goes on behind the scenes when ASP.NET processes the first HTTP request for an ASPX file:

  1. It creates a temporary file containing a class derived from System.Web.UI.Page. The Page class is one of the most important classes in ASP.NET; it represents ASP.NET Web pages.

  2. ASP.NET copies the code in the ASPX file, as well as some code of its own, to the Page-derived class. A method named OnAdd in a <script> block in an ASPX file becomes a member method of the derived class.

  3. ASP.NET compiles the derived class and places the resulting DLL in a system folder. The DLL is cached so that steps 1 and 2 won't have to be repeated unless the contents of the ASPX file change.

  4. ASP.NET instantiates the derived class and "executes" it by calling a series of methods on it. It is during this execution phase that the Page object instantiates any controls declared inside it and solicits their output.

As a Page object executes, it fires a series of events that can be processed by server-side scripts. The most important are Init, which is fired when the page is first instantiated, and Load, which is fired after the page's controls are created but before the page renders any output. The Load event is particularly important to ASP.NET developers because a Load handler is the perfect place to initialize any controls that require dynamic (that is, run-time) initialization. The next section offers an example.

If you want to see the DLLs that ASP.NET generates from your ASPX files, you'll find them in subdirectories under the Windows (or Winnt) directory's Microsoft.NET\Framework\vn.n.nnnn\Temporary ASP.NET Files subdirectory, where n.n.nnnn is the version number of the .NET Framework installed on your PC. Drill down to the bottom of the directory tree under Temporary ASP.NET Files\root, for example, and you'll find a DLL containing the class that ASP.NET derived from Page to serve Calc.aspx (assuming you ran Calc.aspx from \Inetpub\wwwroot). If the subdirectory contains several DLLs, open them with ILDASM, and you'll find one containing a Page-derived class named Calc_aspx. (See Figure 5-8.) That's the class ASP.NET instantiates each time a request arrives for Calc.aspx. If Calc.aspx changes, ASP.NET recompiles the DLL on the next request. Otherwise, the DLL remains on your hard disk so that ASP.NET can reuse it as needed.


Figure 5-8. DLL generated from Calc.aspx.

The Page.Load Event and the Page.IsPostBack Property

Suppose you want to build a Web form that displays today's date and the four days following it in a drop-down list. If today is January 1, 2002, one solution is to statically initialize a DropDownList control:

<asp:DropDownList ID="MyList" RunAt="server">
  <asp:ListItem Text="January 1, 2002" RunAt="server" />
  <asp:ListItem Text="January 2, 2002" RunAt="server" />
  <asp:ListItem Text="January 3, 2002" RunAt="server" />
  <asp:ListItem Text="January 4, 2002" RunAt="server" />
  <asp:ListItem Text="January 5, 2002" RunAt="server" />
</asp:DropDownList>

The problem with this approach is obvious: every day you'll have to modify the form to update the dates. A smarter approach is to write a handler for the page's Load event that initializes the DropDownList at run time:

<asp:DropDownList ID="MyList" RunAt="server" />
  .
  .
  .
<script language="C#" runat="server">
  void Page_Load (Object sender, EventArgs e)
  {
    if (!IsPostBack) {
      for (int i=0; i<5; i++) {
        DateTime date =
          DateTime.Today + new TimeSpan (i, 0, 0, 0);
        MyList.Items.Add (date.ToString ("MMMM dd, yyyy"));
      }
    }
  }
</script>

A Page_Load method prototyped this way is automatically called by ASP.NET when the page fires a Load event. You don't have to manually wire the event to the handler as you do for controls. The same is true for all page-level events. You can respond to any event fired by Page by writing a method named Page_EventName, where EventName is the name of the event you want to handle.

The Page_Load handler in the previous example adds items to the DropDownList by calling Add on the control's Items collection. Items represents the items in the DropDownList. Significantly, this implementation of Page_Load initializes the control only if a value named IsPostBack is false. IsPostBack is one of several properties defined in the Page class. Because all code in an ASPX file executes in the context of a class derived from Page, your code enjoys intrinsic access to Page properties and methods. IsPostBack is a particularly important property because it reveals whether your code is executing because the page was requested from the Web server with an HTTP GET (IsPostBack==false) or because the page was posted back to the server (IsPostBack==true). In general, you don't want to initialize a Web control during a postback because ASP.NET maintains the control's state for you. If you call Add on the control's Items collection the first time the page is fetched and then call it again when the page is posted back, the control will have twice as many items in it following the first postback.

The Page.Init Event

Page_Load methods are handy for performing run-time control initializations. You can also write Page_Init methods that fire in response to Init events. One use for Init events is to create controls and add them to the page at run time. Another is to programmatically wire events to event handlers. For example, instead of connecting Click events to an event handler with an OnClick attribute, like this:

<asp:Button Text="  =  " OnClick="OnAdd" RunAt="server" />
  .
  .
  .
<script language="C#" runat="server">
  void OnAdd (Object sender, EventArgs e)
  {
    int a = Convert.ToInt32 (op1.Text);
    int b = Convert.ToInt32 (op2.Text);
    Sum.Text = (a + b).ToString ();
  }
</script>

you could connect them programmatically in this manner:

<asp:Button Text="  =  " ID="EqualsButton" RunAt="server" />
  .
  .
  .
<script language="C#" runat="server">
  void Page_Init (Object sender, EventArgs e)
  {
    EqualsButton.Click += new EventHandler (OnAdd);
  }

  void OnAdd (Object sender, EventArgs e)
  {
    int a = Convert.ToInt32 (op1.Text);
    int b = Convert.ToInt32 (op2.Text);
    Sum.Text = (a + b).ToString ();
  }
</script>

This is the technique that Visual Studio .NET uses to wire events to event handlers. You'll see an example at the end of this chapter when you build a Web Forms application with Visual Studio .NET.

  Go to page: Prev  1  2  3  4  5  Next  

*JavaScript is a registered trademark of Sun Microsystems, Inc.



JupiterOnlineMedia

internet.comearthweb.comDevx.commediabistro.comGraphics.com

Search:

Jupitermedia Corporation has two divisions: Jupiterimages and JupiterOnlineMedia

Jupitermedia Corporate Info


Legal Notices, Licensing, Reprints, & Permissions, Privacy Policy.

Advertise | Newsletters | Tech Jobs | Shopping | E-mail Offers