好得很程序员自学网

<tfoot draggable='sEl'></tfoot>

ASP.NET的事件模型

ASP.NET的事件模型

当我们新建一个ASP.NET的应用程序时,会默认生成一个Default.aspx和Default.aspx.cs页面。
在Default.aspx的页面中第一行是一条页面指令:

<%@ Page Language="C#" AutoEventWireup="true" CodeBehind="Default.aspx.cs" Inherits="AspxEventsModel._Defaul t" %>

其中CodeBehind属性指定代码隐藏页面的名称,Inherits指定所属的命名空间和类,AutoEventWireup属性是可以赋值为true和false,默认是赋值为true。
我们先在Default.aspx页面中放入两个Literal控件:

        <asp:Literal ID="LiInit" runat="server"></asp:Literal>
        <br />
        <asp:Literal ID="LiLoad" runat="server"></asp:Literal>

在Default.aspx.cs页面中,默认会存在Page_Load方法,定义如下:

         protected  void  Page_Load(object sender, EventArgs e)
        {
             this .LiLoad.Text = "这是在页面Load事件";
        }

页面被请求,在页面加载的时候会执行该方法。

那么这个方法为什么会在页面加载的时候执行,这个方法我们并没有给它注册给页面相应的事件。
页面的事件也有很多,我们列出一些重要页面的事件看一下:
在Page类中存在下面的事件,Page类是页面的基类:

         public  event  EventHandler InitComplete;


         public  event  EventHandler LoadComplete;

         public  event  EventHandler PreInit;

         public  event  EventHandler PreLoad;

         public  event  EventHandler PreRenderComplete;

         public  event  EventHandler SaveStateComplete;

在Control类中存在下面的事件,Control类是Page类的基类:

         public  event  EventHandler DataBinding;

         public  event  EventHandler Disposed;
 
         public  event  EventHandler Init;

         public  event  EventHandler Load;

         public  event  EventHandler PreRender;

我们对这其中比较关注的事件提取出来,并根据事件的执行顺序来排序:
PreInit:在页面的初始化阶段开始时引发
Init:在页面的初始化时引发
InitComplete:在页面的初始化结束时引发
PreLoad:在页面的加载阶段开始时引发   
Load:在页面的加载时引发
LoadComplete:在页面的加载结束时引发
PreRender:在页面即将被呈现时引发

我们看到页面事件有很多,主要来研究Init和Load这两个事件。在Default.aspx.cs页面中,添加Page_Init方法,定义如下:

         protected  void  Page_Init(object sender, EventArgs e)
        {
             this .LiInit.Text = "这是在页面Init事件";
        }

那么还是回到上面的问题,为什么会在页面请求之后执行Page_Init、Page_Load方法?原因是:
ASP.NET中AutoEventWireup="true",使页面与某些特殊的事件方法绑定,自动识别这些具有特定名称的方法,而不需要进行注册事件。
这些特定名称包括:Page_Init, Page_Load等。这里就说明:Init事件会自动与Page_Init方法绑定,Load事件自动与Page_Load方法绑定。当然这些都是AutoEventWireup="true"的功劳,当我们AutoEventWireup="false"的时候,再次请求页面的时候,Page_Init、Page_Load方法是不会被执行的。那么我们可以显示注册事件:

         protected  override  void  OnInit(EventArgs e)
        {
             this .Init +=  new  EventHandler( this .Page_Init);
             base .OnInit(e);
        }
         protected  override  void  OnLoad(EventArgs e)
        {
             this .Load +=  new  EventHandler( this .Page_Load);
             base .OnLoad(e);
        }

那么OnInit和OnLoad又是什么来头呢?
它们是Control类中定义的虚方法,所以我们可以在它的子类里面进行重写。
看ASP.NET 的注释是这样描写的:
OnInit:引发 System.Web.UI.Control.Init 的事件。
OnLoad:引发 System.Web.UI.Control.Load 的事件。

很好啊,我们在这边对它们重写,并注册事件合情合理。
我们把对Init注册事件语句放到OnLoad方法中,把对Load注册事件语句放到OnInit方法中,是两个处理的内容交换一下看看会有什么结果:

         protected  override  void  OnInit(EventArgs e)
        {
             this .Load +=  new  EventHandler( this .Page_Load);
             base .OnInit(e);
        }
         protected  override  void  OnLoad(EventArgs e)
        {
             this .Init +=  new  EventHandler( this .Page_Init);
             base .OnLoad(e);
        }

我们请求页面发现:在OnInit方法中对Load注册事件执行了,在OnLoad方法中对Init注册事件并没有执行。原因是在执行OnInit方法之后,就表示Init事件已经响应完成,在之后再对Init事件注册方法,并不会得到调用。而在OnInit方法中对Load注册事件的时候,Load事件并没有开始触发,这个时候对Load注册事件是有效的。所以现在我们很多时候,都形成了一种规范,只会重写OnInit方法,不重写OnLoad方法,也能完成我们的需求。所以在有些框架里面看不到OnLoad方法就是这样形成的。我们把Default.aspx.cs页面调整成:

        protected override void OnInit(EventArgs e)
        {
            this.Init += new EventHandler(this.Page_Init);
            this.Load += new EventHandler(this.Page_Load);
            base.OnInit(e);
        }

很明显我们觉得不需要Page_Init和Page_Load方法,我们再次调整为:

         protected  override  void  OnInit(EventArgs e)
        {
             this .LiInit.Text = "这是在页面Init事件";
             this .LiLoad.Text = "这是在页面Load事件";
             base .OnInit(e);
        }

我附上调试的源码Default.aspx:

<%@ Page Language= " C# "  AutoEventWireup= " false "  CodeBehind= " Default.aspx.cs "  Inherits= " AspxEventsModel._Default "  %>

<!DOCTYPE html PUBLIC  " -//W3C//DTD XHTML 1.0 Transitional//EN "   " http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd " >
<html xmlns= " http://www.w3.org/1999/xhtml " >
<head runat= " server " >
    <title></title>
</head>
<body>
    <asp:Literal ID= " LiInit "  runat= " server " ></asp:Literal>
    <br />
    <asp:Literal ID= " LiLoad "  runat= " server " ></asp:Literal>
</body>
</html>

Default.aspx.cs:

using  System;
using  System.Collections.Generic;
using  System.Linq;
using  System.Web;
using  System.Web.UI;
using  System.Web.UI.WebControls;

namespace  AspxEventsModel
{
     public   partial   class  _Default : System.Web.UI.Page
    {
         protected   override   void  OnInit(EventArgs e)
        {
             this .LiInit.Text =  " 这是在页面Init事件 " ;
             this .LiLoad.Text =  " 这是在页面Load事件 " ;
             // this.Init += new EventHandler(this.Page_Init);
             // this.Load += new EventHandler(this.Page_Load);
             base .OnInit(e);
        }
         // protected override void OnLoad(EventArgs e)
         // {
         //     this.Load += new EventHandler(this.Page_Load);
         //      // this.Init += new EventHandler(this.Page_Init);
         //     base.OnLoad(e);
         // }
         // protected void Page_Init(object sender, EventArgs e)
         // {
         //     this.LiInit.Text = "这是在页面Init事件";
         // }
         // protected void Page_Load(object sender, EventArgs e)
         // {
         //     this.LiLoad.Text = "这是在页面Load事件";
         // }
    }
}

作者: Leo_wl

    

出处: http://www.cnblogs.com/Leo_wl/

    

本文版权归作者和博客园共有,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文连接,否则保留追究法律责任的权利。

版权信息

查看更多关于ASP.NET的事件模型的详细内容...

  阅读:59次