zoukankan      html  css  js  c++  java
  • web控件开发系列(二) 页面与控件生命周期

     控件在WEB开发时经常要用到,虽然有部分已经存在工具箱里,但有时总需要根据自己的要求,开发一些合适自己的控件。web控件开发已经成为WEB程序员必备的知识。

    这节将会讲述页面与控件的生命周期。页面与控件的生命周期都差不多,大约有以下几个步骤,上一节也讲述过文字理论,本节将从代码方面深入理解。

    生命周期大概有如下几个:
    ·实例化(Instantiate)
    控件被页面或另一个控件通过调用它的构造器所实例化。这个步骤之后所列出的阶段,仅当控件加入控件树中才会发生。

    ·初始化(Initialize)
    初始化在传入 Web 请求生命周期内所需的设置。在此阶段,控件树中的页面和全部控件通过默认方式来调用OnInit方法。开发人员可以通过重载OnInit方法,为控件提供初始化逻辑。在其生命周期的这个时候,控件能够安全地访问其置于Controls集合中的子控件,但是它不能访问控件层次中的父控件或其他层次更高的控件(如页面)

    ·开始跟踪视图状态(Begin Tracking View State)
    这个阶段发生在初始化阶段的末尾。在此阶段页面自动调用TrackViewState方法。TrackViewState方法保证在此阶段之后,使用ViewState字典属性而产生的变化保存在控件视图状态中。在大多数情况下,Control基类提供的TrackViewState方法实现已经足够了,只有在控件定义了复杂属性时,才必须重载TrackViewState方法。

    ·加载视图状态(仅用于回传过程)(Load View State (postback only))
    这个阶段发生在回传时,而不是初始请求过程中,在此阶段结束时,就会自动填充控件的 ViewState 属性控件可以重写 LoadViewState 方法的默认实现,以自定义状态还原。

    ·加载回传数据(仅用于回传过程,为可选项)(Load Postback Data(postback only, optional))
    只有在控件通过实现IPostBackDataHandler接口参与了回传数据处理时,这个阶段才发生在回传中。TextBox控件就是一个例子。在这个阶段中,控件必须从已发送的表单数据中,通过实现IPostBackDataHandler接口的LoadPostData方法更新其状态。

    ·加载(Load)
    直到此阶段开始,控件树中的所有控件都已被初始化,并恢复到它们在先前周期最后的状态。OnLoad方法会执行所有请求共有的操作,如设置数据库查询。此时,树中的服务器控件已创建并初始化、状态已还原并且窗体控件反映了客户端的数据。如果需要实现仅在页面初始请求中执行的逻辑,那么实现该逻辑时,应该检查页面的IsPostBack属性

    ·引发修改事件(仅用于回传过程,为可选项)(Raise Changed Events(postback only, optional))
    只有在控件通过实现IPostBackDataHandler接口参与了回传数据处理时,这个阶段才发生在回传中。在此阶段中,控件通过引发事件(如TextBox的TextChanged事件)作为一种信号-----其状态由于回传而改变(引发更改事件以响应当前和以前回发之间的状态更改)。为了参与此阶段,控件必须实现IPostBackDataHandler接口的RaisePostDataChangedEvent方法。

    ·引发回传事件(仅用于回传过程,为可选项)(Raise Postback Events(postback only, optional))
    只有在控件通过实现IPostBackEventHandler接口参与了回传数据处理时,这个阶段才发生在回传中。在此阶段可以通过实现IPostBackEventHandler接口的RaisePostBackEvent方法来实现逻辑,以便把客户端事件映射到服务器端事件。

    ·预生成(PreRender)
    在此阶段中,应该通过重载OnPreRender方法,执行在生成控件之前所需要的任何工作。在生成输出之前执行任何更新,可以保存在预生成阶段对控件状态所做的更改,而在生成阶段所对应的更改则会丢失。

    ·保存视图状态(Save View State)
    如果控件不维持状态,或者它为保存其所有状态信息而使用ViewState字典,那么不必在此阶段期间实现任何附加逻辑。在此阶段期间,页面框架会自动保存ViewState字典。如果需要自定义状态管理,必须通过重载SaveViewState方法来实现自定义状态恢复,这种方法只被EnableViewState属性为true的控件所调用。在此阶段以后任何控件的改变都不会保存在控件的视图状态中。

    ·生成(Render)
    通过这种方法,控件在输出流上通过重载Control的Render方法或WebControl类的rendering方法中的一种,来写标记文本。

    ·卸载(Unload)
    在此阶段中,页面通过实现Page_Unload方法,来执行清除工作。作为控件开发者,应该重载Dispose方法来执行清除。

    ·释放(Dispose)
    在此阶段,应该重载Dispose方法来释放控件所占的全部资源。

    下面大家在ServerControl下添加ControlLife类,并输下面的代码 

    using System;
    using System.Collections.Specialized;
    using System.ComponentModel;
    using System.Web;
    using System.Web.UI;
    using System.Web.UI.WebControls;

    namespace ServerControl
    {
        
    public class ContrlLife : WebControl , IPostBackDataHandler, IPostBackEventHandler
        {
            
    protected override void OnInit(EventArgs e)
            {
                OutPut(
    "1.  OnInit");
                
    base.OnInit(e);
                
    this.Page.RegisterRequiresPostBack(this);
            }

            
    protected override void LoadViewState(object savedState)
            {
                OutPut(
    "2.  LoadViewState");
                
    base.LoadViewState(savedState);
            }

            
    public virtual bool LoadPostData(string postDataKey, NameValueCollection postCollection)
            {
                OutPut(
    "3.  LoadPostData");
                
    return true;
            }

            
    protected override void OnLoad(EventArgs e)
            {
                OutPut(
    "4  OnLoad");
                
    base.OnLoad(e);
            }

            
    public virtual void RaisePostDataChangedEvent()
            {
                OutPut(
    "5.  RaisePostDataChangedEvent");
            }

            
    public void RaisePostBackEvent(string eventArgument)
            {
                OutPut(
    "6.  RaisePostBackEvent");
            }

            
    protected override void OnPreRender(EventArgs e)
            {
                OutPut(
    "7.  OnPreRender");
                
    base.OnPreRender(e);
            }

            
    protected override object SaveViewState()
            {
                OutPut(
    "8.  SaveViewState");
                
    base.SaveViewState();
                
    return new Pair();
            }

            
    protected override void Render(HtmlTextWriter writer)
            {
                writer.Write(
    "<input type=button name=\"{0}\" value=\"click\" onclick=\"{1}\">""生命周期", Page.ClientScript.GetPostBackEventReference(this""));
                OutPut(
    "9.  Render");
                
    base.Render(writer);
            }

            
    protected override void OnUnload(EventArgs e)
            {
                OutPut(
    "10.  OnUnload");
                
    base.OnUnload(e);
            }

            
    public override void Dispose()
            {
                OutPut(
    "11.  Dispose");
                
    base.Dispose();
            }

            
    private void OutPut(string strText)
            {
                
    if (this.DesignMode == false)
                {
                    HttpContext.Current.Response.Write(strText 
    + "<br>");
                }
            }
        }
    }

    编译,在Default.aspx上拖入这个控件(为了不混乱,先把Default.aspx上的控件都删掉先),运行时你就会看到页面上输出的文字,
    再点击按钮时,就会触发PostBack系列的事件。这时页面上的文字就会多出现几行。
    Web也支持单步调试,你把一个断点设在ContrlLife的代码上,再运行就会发现,可以调试了。

    注意上面,继承了WebControl类和二个接口IPostBackDataHandler, IPostBackEventHandler。

    WebControl: 用作定义 System.Web.UI.WebControls 命名空间中的所有控件的公共方法、属性和事件的基类。是开发Web控件的基础,我们开发时都要继承此类的基础上进行开发。

    IPostBackDataHandler: 定义 ASP.NET 服务器控件为自动加载回发数据而必须实现的方法。包括了下面二个方法
    bool LoadPostData(string postDataKey, NameValueCollection postCollection)
    当由某个类实现时,它为 ASP.NET 服务器控件处理回发数据。
    void RaisePostDataChangedEvent()
    当由类实现时,它用信号要求服务器控件对象通知 ASP.NET 应用程序该控件的状态已更改。


    IPostBackEventHandler: 定义 ASP.NET 服务器控件为处理回发事件而必须实现的方法。只有一个方法

    void RaisePostBackEvent(string eventArgument)
    当由类实现时,使服务器控件能够处理将窗体发送到服务器时引发的事件。

    下个章节将会介绍,控件的生成与输出的过程与方法。

  • 相关阅读:
    如何优雅地结束线程的生命周期
    线程的interrupt()
    线程的join()方法
    守护线程Daemon
    使用多线程模拟一个银行叫号窗口
    多线程介绍
    十八、MySQL 数据排名查询某条数据是总数据的第几条
    spring cloud stream整合
    036线程进程(重要)
    035server端并发聊天
  • 原文地址:https://www.cnblogs.com/whtydn/p/1558551.html
Copyright © 2011-2022 走看看