Asp.net控件开发学习笔记(十)----服务器控件生命周期

 

在每一次httpRequestResponse周期asp.net web form都会执行一系列被称为控件生命周期的预定义过程


   
    在第一次通过
HTTP Get方法获取到页面后,每一次向服务端进行HTTP POST回传都会分为以下几个步骤:

1.      初始化控件树

2.       将回传的ViewState进行解析

3.      根据前几次的回传解析来为控件树中的每一个控件设置状态

4.      处理回传数据

5.      处理Page_Load事件

6.      通过PostBack通知控件的数据变化,并在必要的情况下更新控件状态

7.      执行基于控件状态改变的服务端事件(比如button的点击)

8.      将控件状态持久化为ViewState

9.      按照次序Render控件树中的每一个控件

10. Dispose整个页面和控件树

 

   由上面的列表可以看出整个的用户Request和服务器Response的周期,首先是将状态解析并根据控件的状态来处理状态的改变,最后处理完后将这些Render回客户端,并将新的状态以ViewState的形式保存在客户端的hidden form中。

 

 

  页面生命周期对应事件

  在页面生命周期中,上面所说的每一个步骤都有一个对应的事件。这也就意味着你可以通过Override事件的执行方法来在页面周期中插入你自己的实现

  

服务端事件

页面生命周期

描述

Init

Initialization

初始化控件树

LoadViewState

Unpack ViewState

ViewState里提取出状态信息

LoadControlState

Unpack control state

从控件状态中提取出状态信息

LoadPostData

Handle form postback

PostBack信息中更新控件状态信息

Load

Page_Load event

执行Page_Load内的事件

TrackViewState

Track ViewState

 

RaisePostDataChangedEvent

Initialization for

server-side events

通知控件回传的状态将改变其值

RaisePostBackEvent

Execute server-side events

对于指定的控件,如果状态信息改变,则引发该事件

PreRender

Render process

让每个空间接收最新的状态信息

SaveViewState

Save ViewState

保存ViewState

SaveControlState

Save control state

 

Render

Render process

Render标准HTML,RenderHTML带有控件的状态信息

Dispose

Dispose of control tree

释放资源

 

服务器生命周期和HTTP GET以及HTTP POST

   System.Web.UI.Control基类定义了OnInit, OnLoad, OnPreRender, OnUnload,这四个事件可以被重写。而对于Dispose事件虽然Control也有定义,但并没有相应的OnDispose方法来引发事件,如果需要Dispose事件,需要实现IDispose接口。

   在通常情况下,第一次访问aspx页面时通过HTTP GET方法,而第二次以后都会通过HTTP POST方法,而HTTP POST方式进行访问服务器时,所需要经历的过程要比GET方式多,因为它包含了数据回传处理,下面是示意图:

   

 

   下面通过一个小Demo来查看控件的生命周期:

Demo Post回传生命周期

 

 首先先写一个控件,对每个控件的上述事件进行覆盖,最后通过在页面Trace来查看

 

   首先是控件的代码:

using System;

using System.Collections.Generic;

using System.Linq;

using System.Web;

using System.Web.UI;

 

namespace Life

{

    [ToolboxData("<{0}:lifecycle runat=server></{0}:lifecycle>")]

    public class Lifecycle : Control, IPostBackEventHandler, IPostBackDataHandler

    {

        protected override void OnInit(System.EventArgs e)

        {

            Trace("Lifecycle: Init Event.");

            base.OnInit(e);

        }

        protected override void TrackViewState()

        {

            Trace("Lifecycle: Track ViewState.");

            base.TrackViewState();

        }

        protected override void LoadViewState(object savedState)

        {

            Trace("Lifecycle: Load ViewState Event.");

            base.LoadViewState(savedState);

        }

        protected override void LoadControlState(object savedState)

        {

            Trace("Lifecycle: Load ControlState Event.");

            base.LoadControlState(savedState);

        }

        public override void DataBind()

        {

            Trace("Lifecycle: DataBind Event.");

            base.DataBind();

        }

        public bool LoadPostData(string postDataKey,NameValueCollection postCollection)

        {

            Trace("Lifecycle: Load PostBack Data Event.");

            Page.RegisterRequiresRaiseEvent(this);

            return true;

        }

        protected override void OnLoad(System.EventArgs e)

        {

            Trace("Lifecycle: Load Event.");

            base.OnLoad(e);

        }

        public void RaisePostDataChangedEvent()

        {

            Trace("Lifecycle: Post Data Changed Event.");

        }

        public void RaisePostBackEvent(string argument)

        {

            Trace("Lifecycle: PostBack Event.");

        }

        protected override void OnPreRender(System.EventArgs e)

        {

            Trace("Lifecycle: PreRender Event.");

            Page.RegisterRequiresPostBack(this);

            base.OnPreRender(e);

        }

        protected override object SaveViewState()

        {

            Trace("Lifecycle: Save ViewState.");

            return base.SaveViewState();

        }

        protected override object SaveControlState()

        {

            Trace("Lifecycle: Save ControlState.");

            return base.SaveControlState();

        }

        protected override void Render(HtmlTextWriter writer)

        {

            base.Render(writer);

            Trace("Lifecycle: Render Event.");

            writer.Write("<h3>LifeCycle Control</h3>");

        }

        protected override void OnUnload(System.EventArgs e)

        {

            Trace("Lifecycle: Unload Event.");

            base.OnUnload(e);

        }

        public override void Dispose()

        {

            Trace("Lifecycle: Dispose Event.");

            base.Dispose();

        }

        private void Trace(string info)

        {

            if (Context != null)

            {

                Context.Trace.Warn(info);

               System.Diagnostics.Debug.WriteLine(info);

            }

        }

    }

}

首先通过设置私有的Trace方法将Trace信息添加进页面当中,通过实现了IPostBackEventHandler和IPostBackDataHandler接口来实现Post方式回传所需要的几个方法。

 控件在前台的代码如下:

 首先在前台将Trace属性设置成True,其次注册控件

<%@ Page Language="C#" AutoEventWireup="true" CodeFile="Default10.aspx.cs" Inherits="Default10" Trace="true" %>

<%@ Register Namespace="Life" TagPrefix="lc" %>

 

然后将控件放在页面内:

<lc:Lifecycle runat="server"></lc:Lifecycle>

输出结果如下:

  


   可以看出,我们对事件的实现都已经插入页面的生命周期内.

posted @ 2009-10-15 19:36  CareySon  阅读(4633)  评论(8编辑  收藏  举报