代码改变世界

【转】Asp.net控件开发学习笔记整理篇 - 服务器控件生命周期

2013-12-22 15:49  朱峰(Peter.zhu)  阅读(241)  评论(0编辑  收藏  举报

最近一直在做MVC项目,对于WEBFORM 好像快忘记了。周末无聊,顺带看看他人的笔记。再次温习下。

复习大纲:

导航、页面生命周期及其它导论

一、服务器控件生命周期

二、控件开发基础

三、Asp.net服务端状态管理

四、Asp.net客户端状态管理

五、数据回传

六、WebControl基类

七、服务器控件事件

 

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基类定义了OnInitOnLoadOnPreRenderOnUnload,这四个事件可以被重写。而对于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 : ControlIPostBackEventHandlerIPostBackDataHandler

    {

        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>

输出结果如下:

  


  

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

 

原文引自:http://www.cnblogs.com/CareySon/archive/2009/10/15/1584106.html