程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 編程語言 >> .NET網頁編程 >> 關於.NET >> 深入理解.net服務器控件

深入理解.net服務器控件

編輯:關於.NET

控件生命周期

1.初始化(對應Oninit方法)

這裡頁面通過ProcessRequest方法來遞歸遍歷它的子控件(即頁面中的空間,其實頁面也算控件)。使子控件依次調用它們的Oninit方法。 我們這裡可以重寫控件的OnInit方法,來擴展控件功能或增加初始化內容。在本階段還要打開視圖狀態跟蹤功能,調用TrackviewState方法, 這樣存儲在viewState對象裡面的值在頁面回發時才能正確灰復到控件屬性中。

2.加載視圖狀態(對應LoadViewState方法)

本階段僅在頁面回發時才執行,加載視圖狀態到控件。在第一次訪問頁面時我們還沒有獲得存儲到視圖狀態的狀態數據。

3.加載回傳數據(對應LoadPostData方法)

在頁面回發時執行。LoadPostData實現IPostBackDataHandler(實現控件數據回傳必須要繼承該接口)的一個方法,該方法參數 NameValueCollection類型的對象裝載了客戶端提交的數據。另外該方法還會比較控件的舊值和新值返回一個bool類型值,以決定是否執行 RaisePostDatachangedEvent方法。

客戶修改窗體數據進行提交後,接收到的投遞的數據是以 “&”符號隔開的一些鍵值串,頁面處理器將投遞的數據集合名稱與頁面控件 的ID一一匹配,根據匹配ID檢索對應的服務器控件有沒有實現 IPostBackDataHandler接口,如果實現了就調用控件的LoadPostData方法,給控 件刷新其值。

4.裝載(對應OnLoad方法)

頁面裝載時調用Page_Load()事件,在依次調用各個控件OnLoad方法.

5.數據回傳事件通知(對應RaisePostDataChangeEvent方法)

在頁面回發時執行。該方法也實現了IPostBackDataHandler接口。當bool值為true代表數據更改了,就執行該方法。

6.觸發回發事件(對應RaisePostBackEvent方法)

在頁面回發時執行。主要是處理引起回發的客戶端事件,成功捕獲回發的客戶端事件進行服務器端的相應處理。也實現了 IPostBackDataHandler接口。可以通過本法的參數來判斷是哪個控件觸發的回發事件,進而執行不同的事件處理邏輯。

7.預呈現(對應OnPreRender方法)

主要完成呈現(Render方法)之前所需要的一些處理。如注冊JavaScript腳本和隱藏域控件等。

8.保存視圖狀態(對應SaveViewState方法)

該方法是把頁面控件視圖信息進行存儲。第一次請求該頁面就會執行該操作。

9.呈現(對應Render方法)

主要將控件標記和字符文本輸出到服務器控件輸出流中。

10.卸載(對應OnUnload方法)

對控件資源清除工作。

可以通過構造一個簡單的服務器控件來熟悉它的生命周期

先創建一個控件庫(新建項目選擇ASP.NET服務器控件)和一個網站,再在類庫中添加一個類(添加新建項選擇ASP.NET 服務器控件)。在 講下列代碼復制到類庫中去。在生成該類庫並在網站中引用該類庫,再在該在網站上新建一個aspx文件,在頁面工具箱中直接將控件拖到頁面 上即可。

代碼

1 using System;
2 using System.Collections.Generic;
3 using System.ComponentModel;
4 using  System.Linq;
5 using System.Text;
6 using System.Web;
7 using System.Web.UI;
8 using  System.Web.UI.WebControls;
9 using System.Collections.Specialized;
10
11 namespace ControlLibrary
12 {
13      [DefaultProperty("Text")]
14     [ToolboxData("<{0}:ControlLifecycle runat=server></ {0}:ControlLifecycle>")]
15     public class ControlLifecycle :  WebControl,IPostBackDataHandler,IPostBackEventHandler
16     {
17         protected override void  OnInit(EventArgs e)
18         {
19             //輸出
20             OutPut ("1.OnInit");
21             base.OnInit(e);
22             //注冊
23              this.Page.RegisterRequiresPostBack(this);
24         }
25 
26         protected override  void LoadViewState(object savedState)
27         {
28             OutPut ("2.LoadViewState");
29             base.LoadViewState(savedState);
30
31         }
32
33         public virtual bool LoadPostData(string postDataKey, NameValueCollection postCollection)
34         {
35 
36             OutPut("3.LoadPostData");
37              return true;
38         }
39
40         protected override void OnLoad(EventArgs e)
41          {
42             OutPut("4.OnLoad");
43             base.OnLoad(e);
44          }
45 
46         public virtual void RaisePostDataChangedEvent()
47          {
48             OutPut("5. RaisePostDataChangedEvent");
49         }
50
51          public virtual void RaisePostBackEvent(string eventArgument)
52         {
53              OutPut("6. RaisePostBackEvent");
54         }
55 
56         private void OutPut(string  strText)
57         {
58             if (this.DesignMode == false)
59              {
60                 HttpContext.Current.Response.Write(strText + "<br>");
61              }
62         }
63
64         protected override void OnPreRender(EventArgs e)
65         {
66             OutPut("7. OnPreRender");
67              base.OnPreRender(e);
68         }
69
70         protected override object SaveViewState()
71          {
72             OutPut("8. SaveViewState");
73              base.SaveViewState();
74             return new Pair();
75         }
76 
77          protected override void Render(HtmlTextWriter writer)
78         {
79              writer.Write("<INPUT type=button name=\"{0}\" value=\"Click Me!\" style='position:absolute; left: 20; top: 280px'  onclick=\"{1}\">", this.UniqueID, Page.ClientScript.GetPostBackEventReference(this, ""));
80              OutPut("9. Render");
81             base.Render(writer);
82         }
83
84      }
85 }
86 

其實上面過程就算是我們開發了一個控件。了解它,最好的辦法是嘗試去開發它。

開發一個控件首先要選好它要繼承的基類

選擇基類

Control

控件開發基類,所有控件都直接或間接繼承該類。提供了各類控件通用的屬性和方法。

WebControl

webcontrol繼承了control所有的屬性,還增加了布局,可訪問性,外觀樣式等特性。

CompositeControl

如果把現有控件聚合起來創建一個組合控件時,可以繼承此類。該類默認實現了INamingContainer接口。

控件呈現順序

上面介紹到了控件Render階段主要是將控件標記和字符文本輸出到服務器控件流當中。這裡可以直接寫HTML標記(上面例子就是的)也可以 調用每個控件都有的RenderControl方法到輸出流。在WebControl中,介紹以下5個函數

RenderControl(HtmlTextWriter writer)

Render(HtmlTextWriter writer)

RenderBeginTag(HtmlTextWriter writer)

RenderContents(HtmlTextWriter writer)

RenderEndTag(HtmlTextWirter writer)

在RenderControl 會內部調用Render,在Render會內部調用RenderBeginTag,RenderContents,RenderEndTag。

其中RenderBeginTag,RenderEndTag可以重寫,默認值為<span></span>。它們是用來定義控件起始和結束的標記。 RenderContents看英文的意思就明白了。(待續)

  1. 上一頁:
  2. 下一頁:
Copyright © 程式師世界 All Rights Reserved