aspx頁面的生存週期

1. PreInit()
         在這個頁面級的事件中,所有在設計時創建的控件都將被用默認值做初始化。例如,如果你有一個Text屬性值爲“Hello”的TextBox控件,則此時這個屬性被設置。我們也可以在這裏動態的創建控件。
         這個事件僅僅發生在頁級別的類中,用戶控件和母版頁沒有這個事件。
         下面的代碼示例瞭如何重寫這個方法以增加你的自定義代碼
         protected override void OnPreInit(EventArgs e)      
         {
             //custom code           
             base.OnPreInit(e);
         }
         注意,我們只能在PreInit()事件中動態的設置themes,且應該在PreInit()事件或該事件之前加載母版頁。

2. OnInit()
         在這個事件裏,我們能讀出控件的屬性(在設計模式中設置的)。但是我們不能讀出用戶設置的值,因爲得到用戶設置的值是在LoadPostData()事件被激發之後。不過在這個事件中我們可以得到POST數據,如下
         string selectedValue = Request.Form[controlID].ToString();

3. LoadViewState
         這個事件僅僅在回發之後被激發(IsPostBack == true)。在這個事件中runtime從隱藏域中分解出view state並加載到所有啓用了view state的控件。

4. LoadPostBackData
         這個事件也僅僅是在回發之後被激發。
         在這個事件裏實現了IPostBackDataHandler接口的控件從HTTP的POST數據中得到值。注意,textbox控件不能從view state中獲得值,而是在此事件中從POST數據中獲得值。所以即使有些控件沒有啓用view state,只要它實現了IPostBackDataHandler接口就可以從HTTP的POST數據中得到值。
         另一個重要的知識點是如果我們有一個DropDownList控件並動態的給它增加一些選擇項,那麼runtime將不能得到這些值除非啓用了view state(即使控件繼承自IPostBackDataHandler接口)。這個原因就是在HTTP的POST數據中的每一個控件只能有一個值,並且POST數據中的所有值都不會被保存,除了使用view state。

5. Page_Load
         這是最常用的方法了,而且是一些開發新手放置他們代碼的第一個地方,有些新手們往往認爲這就是Page類第一個觸發的方法。這個方法是混淆我們Page生存週期的罪魁禍首之一。
         注意:如果頁裏有任何用戶控件的話,那麼用戶控件的Load方法將在頁類的Load方法之後被觸發。除了Init()和Unload()之外的所有事件都是從最外面到最裏面被激發的,所以頁的Page_Load()之後,頁內的其它控件的Load方法才被觸發。

6. Control Event Handlers
         事件處理(比如像Button1_Click()之類的)是定義在ASPX頁面中的,有一些開發人員認爲當單擊一個按鈕後會立即出發Button_Click() ,他們忘了在這個事件觸發之前首先要觸發Page_Load。

7. PreRender
         如果我們想改變某一個控件的值,這是最後的機會了

8. SaveViewState
         控件的ViewState被存儲在form的隱藏域中

9. Render
         呈現頁面和控件

10. Unload
         這是最後的清理操作


動態控件
         現在我們已經知道了頁的生存週期的重要事件,接下來讓我們關注一下如何創建以及保持動態生成控件的狀態。有的時候我們需要動態的生成控件,比如我原來管理的一個酒店預訂的項目,用戶在一個TextBox裏輸入房間號,根據這個值動態的生成一個用戶控件來顯示該房間的詳細信息。
         開發人員雖然能動態的生成用戶控件,但是卻不能保存用戶控件的狀態。當我看了代碼後,他們把生成控件的代碼寫到了Button的Click事件裏。根據我們上面所討論的,Button_Click()在LoadViewState()和LoadPostData()之後觸發,而控件的值是要在view state或POST數據中取得的。
         所以除非在Page_Init()或Pre_Init()方法裏重新創建控件(它們發生在LoadViewState和LoadPostData之前),這樣就可以在下一個事件裏獲得控件的值。
         現在,如果把代碼寫到Page_Init()事件裏的話,將不能得到用戶在TextBox(它是一個靜態控件)裏輸入的值。原因就在於這是Page_Init()事件,控件的值被初始化爲它們設計時的默認值,而不會得到用戶輸入的值。
         所以如果要在這裏訪問到用戶輸入的值話只有一個辦法,就是從POST數據中取值。代碼如下
         protected override void OnInit(EventArgs e)   
         {
             // 通過Post數據得到用戶在TextBox裏輸入的值
             string selectedValue ;
             if(Request.Form["txtNoOfRooms"] != null)              
                 selectedValue = Request.Form["txtNoOfRooms"].ToString();
          
             // 動態生成控件的代碼
             base.OnInit(e);
         }

         如果你在Page_Load事件裏創建一個動態控件,並把它添加到PlaceHolder或Panel裏(要打開view state),那麼動態控件將會維持它的狀態,即使它不是在Page_Init()中創建的,爲什麼?
         原因就是控件一旦被添加到頁的控件樹裏,TrackViewState()方法就負責跟蹤其狀態。只要控件被添加到控件樹裏,這個方法就會被自動的觸發。因爲這個原因,對控件的任何修改(如添加item之類的)都應該在動態控件被添加到頁的控件樹之後來做,否則其狀態將丟失。請看如下代碼
         protected void Page_Load(object sender, EventArgs e)
         {
             // 創建一個DropDownList
             DropDownList d = new DropDownList();
   
             // TrackViewState()方法將被觸發去跟蹤這個DropDownList的狀態,所以其狀態將被保持
             PlaceHolder1.Controls.Add(d);

             if (!IsPostBack)
             {
                 d.Items.Add("test1");
                 d.Items.Add("test2");
             }
         }

         下面的代碼則不會保持動態控件的狀態
         protected void Page_Load(object sender, EventArgs e)
         {
             // 動態創建一個控件
             DropDownList d = new DropDownList();
             if (!IsPostBack)
             {
                 d.Items.Add("test1");
                 d.Items.Add("test2");
             }
   
             // "test1"和"test2"值將丟失
             PlaceHolder1.Controls.Add(d);
         }

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章