.net组件开发系列之武术系列 武术招数 控件生命周期与控件事件机制
一。控件生命周期
??? 先回述上篇,可能表述沒有不清晰,也可能跨度大了點,好的,我們來一個循序漸進過程,大家都知道,武術都有招術的,先出什么,再出什么,什么時候打完收工,都是有順序的,而我們的控件也正如此,它也有一個順序。那我們的這個順序(控件的生命周期)是怎么的.在web這個無狀態http協議的通信中,如何實現了,如何創建一個象webform程序那樣呢。使頁面提供一個連續執行的。答案是。在處理完一個請求之后保存其狀態,在回傳時,在新的請求之前恢復已保存的狀態。
? 頁面(其實也是一個控件,繼承webcontrol)把請求分成幾個階段,能夠用于重新創建和保存頁面及控件樹。那好,我們來看看控件生命期圖:
?(ps:畫得不乍的)
?關于控件生命周期各個階段所發生的事,網上很多很多,詳見:
http://blog.csdn.net/SysBug/archive/2007/06/04/1638013.aspx(很詳細的)
我們的主要在于分析執行機制,分了說明其執行順序,我們舉個例先:
?我們在這樣做的。就是重寫控件生命周期的每個階段,并且寫入一些簡單消息,然后,我們分三種。我們先將控件直接注冊到頁面上,一種是動態注冊控件,一種是實例化控件,但不加到控件樹上。然后通過啟用trace="true"去頁面追蹤.
先了一個控件,代碼如下:
using?System;
using?System.Data;
using?System.Configuration;
using?System.Web;
using?System.Web.Security;
using?System.Web.UI;
using?System.Web.UI.WebControls;
using?System.Web.UI.WebControls.WebParts;
using?System.Web.UI.HtmlControls;
/**////?<summary>
///?ConDemo?的摘要說明
///?</summary>
///?
namespace?cnblogs
{
????public?class?ConDemo?:?Control
????{
????????protected?override?void?OnInit(EventArgs?e)
????????{
????????????base.OnInit(e);
????????????Page.Trace.Warn(this.UniqueID,?"在初始化階段");
????????}
????????protected?override?void?TrackViewState()
????????{
????????????base.TrackViewState();
????????????Page.Trace.Write(this.UniqueID,?"在加載視圖。。。");
????????}
????????protected?override?void?LoadViewState(object?savedState)
????????{
????????????base.LoadViewState(savedState);
????????????Page.Trace.Write(this.ID,?"在保存視圖階段");
????????}
????????protected?override?void?OnLoad(EventArgs?e)
????????{
????????????base.OnLoad(e);
????????????Page.Trace.Write(this.UniqueID,?"?在加載中。。。");
????????}
????????protected?override?object?SaveViewState()
????????{
????????????Page.Trace.Write(this.UniqueID,?"?在保存視圖狀態..");
????????????return?base.SaveViewState();
????????????
????????}
????????protected?override?void?OnPreRender(EventArgs?e)
????????{
????????????base.OnPreRender(e);
????????????Page.Trace.Write(this.UniqueID,?"在預呈現");
????????}
????????protected?override?void?Render(HtmlTextWriter?writer)
????????{
????????????Page.Trace.Write(this.UniqueID,?"在呈現..");
????????????base.Render(writer);
????????}
????????public?override?void?Dispose()
????????{
???????????
????????????base.Dispose();
????????}
????????public?ConDemo()
????????{
????????????//
????????????//?TODO:?在此處添加構造函數邏輯
????????????//
????????}
????}
}
?
然后在aspx 寫上如下代碼
注意:記得啟動 Trace="true"
<%@?Page?Language="C#"??Trace="true"?AutoEventWireup="true"??CodeFile="Default.aspx.cs"?Inherits="_Default"?%>
<%@?Register?Namespace="cnblogs"?TagPrefix="tt"?%>
<!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>
????<form?id="form1"?runat="server">
????<div>
????<tt:ConDemo?runat=server?ID="Condemo1"></tt:ConDemo>
??????????<%--控件添加?--%>
????????<asp:Button?ID="Button1"?runat="server"?Text="加載控件"?OnClick="Button1_Click"?/>
????????
??????<%--產生回傳?--%>
????????<asp:Button?ID="Button2"?runat="server"?Text="postback"?/></div>
????</form>
????
</body>
</html>
在cs頁面
using?System;
using?System.Data;
using?System.Configuration;
using?System.Web;
using?System.Web.Security;
using?System.Web.UI;
using?System.Web.UI.WebControls;
using?System.Web.UI.WebControls.WebParts;
using?System.Web.UI.HtmlControls;
public?partial?class?_Default?:?System.Web.UI.Page?
{
????protected?void?Page_Load(object?sender,?EventArgs?e)
????{
????}
????protected?void?Button1_Click(object?sender,?EventArgs?e)
????{
????????cnblogs.ConDemo?dy?=?new?cnblogs.ConDemo();
????????dy.ID="dynamic1";
????????this.Controls.Add(dy);
????????cnblogs.ConDemo?dy2=new?cnblogs.ConDemo();
????????dy2.ID="dynamic2";
????}
}
?這些工作做完后,我們來分析分析現象。當我在第一次在瀏覽器瀏覽時:我們發現,子控件會在在預覽的時候,可以發現階段Condemo1(自定義控件)的執行順序,當它被加到父控件的Controls里時,父控件會根據其當前的control階段來調用該子控件的一些方法,讓子控件趕上父控件的control階段,
?
? ?
?
??? (圖1)
? 每一個控件內部都保存著它當前的加載進度,也就是它到達了上述的哪一個階段,當我們執行Control.Controls.Add方法來將一個控件添加到另一個控件中時,父控件就會檢查子控件的加載進度,如果子控件的加載進度比自己的慢了,就會要求子控件追趕上來,
當我們點擊"加載控件"按鈕時,發現:
?
?(兩張圖是一起的,截圖的時候的不好截)
????? (圖2)
藍色代表,是動態添加的,紅色是我們在頁面上直接注冊的。
但我們在button 事件還創建了一個自定義控件(dynamic2)實例,可我們沒有把它添加到控件樹上,所以說,除非控件添加到控件樹上,否則它不將參于請求處理,當在頁面上注冊控件時,頁面的解析器會把它加到控件樹上,動態創建的控件,則要自已將控件添加到控件樹上。
從上面圖中,我們還可以看到,另一個信息,就是我們為什么動態添加的控件在回傳后會消失,從圖中,一眼就看出來了,按圖2來說吧,因為當dynamic1動態加載到控件樹上時,可這個控件樹(這里指的是Page頁面)已經完成了加載視圖狀態,從而在后來的恢復視圖中找不到了dynamic1中的視圖了。這樣就解析了動態控件回傳后為什么會消失的問題,經過分析,你可能已經知道了,我們點了"postback"按扭后,控件樹,變成什么樣了吧。
?
現在問題出現了,該如何解決呢?
介紹兩種方法吧:
第一種,就是在OnInit事件中動態加載進去,
示例:
?
?protected?override?void?OnInit(EventArgs?e)
????{??cnblogs.ConDemo?dy=?new?cnblogs.ConDemo();
????????dy.ID="dynamic1";
????????this.Controls.Add(dy);
????????dy.Visible?=?false;
????????base.OnInit(e);
????}
然后在按扭事件中。查找dynamic1控件,將其Visible為true
第二種,見我的(動態添加控件終極解決方案)
地址:http://www.cnblogs.com/suiqirui19872005/archive/2007/10/11/920845.html
二:下一講事件機制,
原本想今天寫事件機制一并寫掉,可我沒有準備好示例,所以,等下一講講吧。
先透露一下,大家都常用IPostBackDataHandler,IPostBackEventHandler了吧,
下一講還有兩個事件注冊。GetPostBackClientHyperlink,GetPostBackEventReference
我們都用過LinkButton吧,我們發現其生成html后,成了
javascript:__doPostBack('LinkButton1',''),其中就用了GetPostBackClientHyperlink,下一節中,將講到。
?
?
PS:自已的表達能力差了點,望大家海含,我在更正當中。
總結
以上是生活随笔為你收集整理的.net组件开发系列之武术系列 武术招数 控件生命周期与控件事件机制的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: SQLServer2k安全配置
- 下一篇: Cisco测试命令和TCP/IP连接故障