欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  IT编程

ASP.NET的事件模型(很适合学习的文章)

程序员文章站 2024-03-06 17:39:08
在default.aspx的页面中第一行是一条页面指令: <%@ page language="c#" autoeventwireup="true" codebeh...

在default.aspx的页面中第一行是一条页面指令:

<%@ page language="c#" autoeventwireup="true" codebehind="default.aspx.cs" inherits="aspxeventsmodel._default" %>

其中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事件";
        //}
    }
}


好了,赶快自己动手试试吧。