页面和控件的生命周期及其二者的关系
前言:
作为开发人员,必须对服务器控件生命周期深刻理解。页面和控件生命周期对服务端控件开发及其重要。没有深刻理解生命周期及其相互先后关系,不能开发复杂清晰条理的自定义控件。
页面经历了哪些过程了呢:
(1)页面首先从QueryString或Request对象的Form集合中获得回调数据。
(2)页面检测回传数据集合(NameValueCollection,Form或者QueryString)中是否包括一个键为__CALLBACKID的项。如果存在则设置IsCallBack为true,以便通过Asp.Net客户端的回调机制,标明页面已经回传到服务器。这个机制以后详谈。
(3)预初始化(PreInit):在此生命周期将完成一下操作,
a.调用OnPreInit方法引发PreInit事件
b.利用App_Themes目录中的内容初始化主题,以便动态实现PageTheme类。
c.应用母版页
(4)初始化(Init):在此生命周期将完成一下操作,
a.递归初始化Controls集合中的控件,包括设置这些控件属性的值,例如ID,Page,NamingCotainer等
b.递归应用控件的皮肤
c.调用OnInit方法引发Init事件,然后递归调用子控件的OnInit方法来引用其Init事件。
d.首先调用页面自身的TrackViewState方法,递归调用子控件的TrackViewState方法来启动(自身的)视图状态跟踪。
(5)完成初始化(InitComplete):
调用OnInitComplete方法来引发InitComplete事件表明初始化阶段完成。此时页面Controls中所有的控件都已经初始化了。
(6)加载控件状态(仅用于回传过程)(Load Control State(Postback Only)):
页面递归调用Controls集合中的LoadControlState方法,这些控件已经调用了Page类的RegisterRequiresControlState方法,以便使用他们的控件状态。
(7)加载视图状态(仅用于回传过程)(Load View State(Postback Only)):
页面首先调用自身的LoadViewState 方法,接着递归调用Controls集合中子控件的LoadViewState方法,以便加载其上次保存的ViewState。
(8)加载回传数据(仅用于回传过程,首次尝试加载)(Load Postback Data (Postback Only-First Try)):
页面调用实现了IPostBackDataHandler接口的控件的方法LoadPostData,并将回传数据传递给改方法。每个控件的LoadPostData方法都必须访问回传数据,并根据此数据可以更新相应控件的属性。
(9)预加载(PreLoad):
页面调用OnPrenLoad方法以引发PreLoad事件,表明页面生命周期进去了加载阶段。
(10)加载(Load):
页面首先调用自身的OnLoad的方法引发Load事件,然后递归调用Controls集合中的子控件的OnLoad方法来引用它们的Load事件。页面开发人员可以为Load事件注册为回调,那样就可以通过编程将子控件添加到页面的Controls集合中。
(11)加载回传函数(仅用于回传过程,第二次尝试加载)(Load Post Data(Postback Only-Second Try)):
页面调用控件的LoadPostData方法。这些控件如果实现了IPostBackDataHandler接口,那么在加载阶段,它们已经通过编程将子控件添加到Controls集合中了。
(12)引发回传数据修改事件(仅用于回传过程)(Raise Post Data Changed Event (Postback Only)):
页面调用控件的RaisePostDataChangedEvent方法,这些控件的LoadPostData方法返回true。RaisePostDataChangedEvent方法引发了回传数据修改事件。例如TextBox的Text值发生了改变与旧值不同,那么起引发该事件。
(13)引发回传事件(仅用于回传过程)(Raise Post Event(Postback Only)):
页面调用控件的RaisePostEvent方法,这些控件相关的HTML标签用于提交表单。eg,Button控件的相关HTML元素将页面回传到服务器。控件的RaisePostBackEvent方法必须将回传事件映射到一个或多个服务端事件。eg,Button控件的RaisePostEvent方法将事件映射到了服务端事件Command或Click上。
(14)完成加载(Load Compelete):
页面调用OnLoadComplete方法来引发LoadCompelet事件。这表明所有加载活动,包括加载回传数据以及引发回传数据修改事件,并以更新控件自身的活动都已经完成了。
(15)引发回调事件(仅用于回传和回调过程)(Raise CallBack Event (Postback and Callback Only)):
页面调用控件的RaiseCallbackEvent方法。该控件可使用Asp.net客户端的回调机制来允许客户端方法(例如JavaScript函数)调用服务端方法,而无需整个页面回传到服务器。RaiseCallbackEvent方法必须调用服务端方法。如果页面的回传使用了客户端机制,那么页面将不会继续执行剩余的页面生命周期阶段。Asp.net回调机制将在以后详谈。
(16)预呈现(PreRender):
完成以下操作,
a.调用EnsureChildControls方法来确保在页面进入呈现阶段之前,创建其子控件。
b.调用自身的OnPreRender方法以引发PreRender事件。
c.递归调用子控件(Controls集合中)的OnPreRend方法,以引发它们的PreRender事件。
(17)预呈现完成(PreRender Complete):
页面调用OnPreRenderComplete方法以引发PreRenderComplete事件,表明整个预呈现过程完成。
(18)保存控件状态(Save Control State):
页面递归调用Controls集合中控件中SaveControlState的方法。这些控件已调用Page类的RegisterRequiresControlState方法来保存他们的控件状态。
(19)保存视图状态(Save View State):
页面首先调用自身的SaveViewState方法,然后递归调用Controls集合中的控件的SaveViewState方法,以便允许他们来保存其视图状态。
(20)保存状态完成(Save State Complete):
页面调用OnSaveStateComplete方法以引发SaveStateComplete事件,这表明所有状态保存活动完成了。
(21)呈现(Rendering):
a.创建一个HtmlTextWriter类实例,该实例封装了输出响应流。
b.调用RenderControl方法,并将HtmlTextWriter实例传递给该方法。
RenderControls方法递归调用子控件的放RenderControl方法,以便允许每个子控件能够呈现其HTML标记文本。子控件的HTML标记文本组成了最终发给客户端浏览器的HTML文本。