利用ASP.NET 2.0建立自訂Web控制項

來源:互聯網
上載者:User
asp.net|web|建立|控制項 從使用基本的文字編輯器到創作標記頁面,Web 開發已經經曆了一個漫長的過程。目前,整合式開發環境 (IDE) 為開發過程中的幾乎每個方面都提供了圖形化表示形式。此外,還實現各種說明性編程技術以提高效率並降低出現錯誤的幾率。Visual Studio 2005 和 ASP.NET 2.0 中的控制項體繫結構遵循了這些編程趨勢,並且提供了可靠的、可擴充的環境,該環境設計為使開發人員可以建立能夠以說明方式配置的控制項。

  此外,ASP.NET 中新的自適應呈現模型減少了編寫可專門識別其目標瀏覽器的控制項的需要。換句話說,控制項開發人員可以專註於設計控制項,而讓 ASP.NET 架構負責轉換控制項並針對不同類型的瀏覽器和裝置呈現它。

  儘管 ASP.NET 2.0 在控制項設計過程中提供了增量改進功能,但實際控制項呈現模型已經完全進行了更改。作為自訂控制項開發人員,您將會看到利用 ASP.NET 的幾個新選項。最重要的是,您將會發現只需編寫較少的代碼便可完成相同的任務。

  在 ASP.NET 2.0 中,建立自訂伺服器控制項有很多方法,每種方法都有其優點和局限性。本文將討論與自訂控制項的建立和配置相關的詳細資料。程式碼範例和體繫結構概念要求您對 C# 程式設計語言具有中等水平的理解。

  自適應呈現模型

  在 ASP.NET 1.x 中,自訂控制項開發人員必須設計每個伺服器控制項,以便它可以識別不同的瀏覽器類型並發出正確的輸出。ASP.NET 1.x 控制項架構提供了幾項功能以使該任務變得更簡單,但開發人員仍然必鬚根據瀏覽器的類型編寫切換程式、開發適當的 HTML,然後針對不同類型的瀏覽器測試控制項。此外,如果開發人員希望控制項在行動裝置上顯示,他必須建立一個與普通 網頁瀏覽器上使用的控制項不同的全新控制項。

  ASP.NET 2.0 通過新的自適應呈現模型簡化了瀏覽器檢測和呈現過程。在 ASP.NET 2.0 中引入的自適應呈現模型旨在用於支援那些眾多能夠使用標記格式(包括 HTML、WML、XHTML 或 CHMTL)的不同裝置。

  自適應呈現模型體繫結構

  每個控制項都可以連結到一個適配器,它會針對特定的目標裝置修改控制項的行為和標記。例如,HTML 適配器將 ASP.NET 控制項產生為標準的 HTML 和 DHTML,以便普通 網頁瀏覽器使用。另一方面,WML 適配器將相同的控制項轉換成無線傳輸標記語言,以便蜂窩電話或其他行動裝置使用。


圖 1. 控制項-適配器壽命周期
  上圖說明了控制項方法與適配器方法之間一對一的映射。如果有適配器(如果控制項的 Adapter 屬性不為空白),執行就會在控制項和適配器方法之間傳輸,如上圖所示。在產生階段,控制項對象或配接器物件都可以產生輸出(通常情況下兩者不同時產生輸出)。通常情況下,如果有適配器,那麼適配器的實現將覆蓋控制項的實現。在 ASP.NET 2.0 中,自適應呈現模型適用於所有 ASP.NET 控制項(不僅僅是行動控制項),並且允許 ASP.NET 2.0 支援統一的控制項體繫結構。



實際意義

  自適應呈現模型的實際意義有兩個主要方面。第一,作為開發人員,您可以設計一次控制項並期望它可以在具有適配器的任何類型的裝置或瀏覽器上使用。第二,您可以對常用適配器利用廣泛的 Microsoft 測試,減少您自己瀏覽器的特定測試。

  自適應呈現模型還為 ASP.NET 2.0 提供了將其他服務添加到控制項產生過程中的機會。由於具有適配器模型,您可以:

  1) 根據目標的類型,使用篩選器 來更改控制項的外觀。

  2) 根據目標的類型,使用模板來更改整個頁面配置。

  3) 根據瀏覽器控制在瀏覽器上的呈現,而不必依賴於 ASP.NET 1.x 的 uplevel/downlevel 確定。

  在本文中,我們將重點放在建立自訂控制項的應用方面。但是,請牢記自適應呈現模型是新的基礎架構。

  建立自訂伺服器控制項

  Visual Studio 2005 提供了很多用於開發自訂伺服器控制項的有用工具。為了說明某些功能,我們將建立一個 MailLink 控制項,它公開了兩個屬性:Email 和 Text。該控制項將產生必需的 HTML 來將所提供的 Text 封裝到 mailto: 連結標記中。

  建立項目

  在 Visual Studio 2005 中,我們通過在建立項目嚮導中選擇適當的表徵圖來建立一個新的“Web Control Library”項目:


圖 2. Visual Studio 2005 中的建立項目嚮導
  該項目是利用預設的自訂控制項類實現建立的。對於我們的樣本,我們將該預設檔案重新命名為 MailLink.cs。

  註:在方案總管中重新命名該檔案時,Visual Studio 2005 將會自動更新類名。

  MailLink 的原始碼在由項目嚮導產生的預設範本上構建。MailLink 類從 WebControl 基類自動派生。

public class MailLink : WebControl {
  WebControl 類提供預設實現方法,可以很簡單地覆蓋這些方法來為我們的控制項提供詳細說明。

  添加屬性

  在 MailLink 樣本中,我們需要添加 Email 和 Text 屬性。為了正確配置這些屬性,我們不僅必須編寫代碼,還要分配幾個特性。

[Bindable(true),
Category("Appearance"),
DefaultValue(""),
Description("The e-mail address.")]

public virtual string Email {
get {
string s = (string)ViewState["Email"];
return (s == null) ? String.Empty : s;
}
set {
ViewState["Email"] = value;
}
}
  特性(以粗體表示)定義了新控制項將如何與設計器 (Visual Studio) 進行互動。Email 屬性的特性告訴 Visual Studio 如何在設計過程中處理屬性:

  1) Bindable — Email 屬性可綁定 到資料來源。您可以將 Email 欄位連結到資料庫、XML 檔案或任何其他 DataSet。該特性強制 Visual Studio 在控制項的可綁定屬性列表中顯示 Email 屬性。

  2) Appearance —Email 屬性將顯示在 Appearance 類別下的屬性視圖中。您可以選擇想要的任何類別,包括預設類別:Appearance、Accessibility、Behavior、Data、Layout 或 Misc。只要使用者選擇了屬性的類別組織方法,Email 屬性將會顯示在 Appearance 下。

  3) DefaultValue — Email 屬性具有一個空的預設值。儘管空值對於 Email 欄位來說有意義,但對於您添加到控制項中的其他屬性可能並不合適。當使用者將您的控制項放到他們的 Web 頁上時,選擇適當的預設值可為使用者免去不計其數的單擊操作。

  4) Description — 屬性說明顯示在控制項列表下,並且也可能作為工具提示出現。Email 屬性將具有 The e-mail address 說明。

  5) Localizable — 它會用發送訊號的方式通知 ASP.NET 2.0 Framework 該控制項包括可以針對不同語言或位置進行配置的文字屬性。

  您可以使用 System.ComponentModel 命名空間中的各種特性來進一步改進任何特殊屬性的外觀和行為。我們將在本文的使用設計器部分中更詳細地介紹修改屬性或控制項的行為的方法。

  接下來,我們需要添加 Text 屬性。Text 屬性與 Email 屬性稍有不同,因為我們希望將 Text 顯示為由 MailLink 控制項發出的 HTML 的一部分。為此,我們需要從 System.Web.UI 命名空間中添加一個新的特性。

[Bindable(true),
Category("Appearance"),
DefaultValue(""),
Description("The text to display on the link."),
Localizable(true),
PersistenceMode(PersistenceMode.InnerDefaultProperty)]
public virtual string Text {
get {
string s = (string)ViewState["Text"];
return (s == null) ? String.Empty : s;
}
Set {
ViewState["Text"] = value;
}
}
  Text 屬性的 PersistenceMode(PersistenceMode.InnerDefaultProperty) 特性(粗體代碼)指定設計器應該將該屬性作為控制項標記內的內部內容序列化。該特性還聲明 Text 是控制項的預設屬性。當使用者在 Visual Studio 中使用這個控制項時,Text 屬性將會作為該控制項的內部文本自動顯示在圖形設計器上,並且如果使用者單擊該控制項並嘗試更改顯示的文本,Text 屬性將會自動更改。

  另一方面,應用到屬性的特性會影響設計期間使用者與控制項的互動方式。在運行過程中,這些特性被 ASP.NET 運行時忽略。


有關 ViewState 的注釋

  請注意,用於兩個屬性的 Get 和 Set 方法都利用 ViewState 對象。ViewState 對象是一個內建到 WebControl 類中的協助器對象。從開發角度講,ViewState 可被視為一個集合類,用於儲存在回傳過程中我們想要保留的任意屬性。實際上,ViewState 封裝了確定如何執行持久性(使用 Cookie、會話等等)所需的所有代碼和邏輯。

  產生控制項

  在定義了控制項屬性之後,接下來的步驟就是要設計將由控制項發出的實際響應。在 MailLink 樣本中,我們希望設計控制項來產生基本的 HTML 標籤。

  TagKey

  WebControl 的預設實現會產生一個 標記。我們的 MailLink 控制項通過為 TagKey 屬性提供它自己的實現來覆蓋該預設實現。TagKey 屬性定義將要封裝控制項內容的最外面的標記。

  幸運的是,我們可以使用 HtmlTextWriterTag 枚舉來指示連結 標記,而不必實際編寫 HTML 文本。該枚舉方法用於最常用的 HTML 標籤。

protected override HtmlTextWriterTag TagKey {
get {
return HtmlTextWriterTag.A;
}
}
  如果您需要產生一個不屬於 HtmlTextWriterTag 枚舉的一部分的標記,您必須覆蓋 WebControl.TagName 屬性,而非 TagKey 屬性。TagName 屬性會返回由控制項產生的實際 HTML 標籤字串。TagName 的預設 WebControl 實現只調用 TagKey,並以完美的提取方式提取正確的 HTML。

  AttributesToRender

  在定義了基本標記之後,接下來的步驟就是分配我們要添加到該標記中的各種特性。我們的 MailLink 控制項將覆蓋 AddAttibutesToRender 方法以便為“mailto”標記添加適當的標記。

protected override void AddAttributesToRender(
HtmlTextWriter writer){
base.AddAttributesToRender(writer);
writer.AddAttribute(HtmlTextWriterAttribute.Href,
"mailto:" + Email);
}
  對基類的 addAtributeToRender() 調用會被調用,以確保可以正確產生其他樣式和特性。如果我們忽略該基本調用,我們可能會失去內建到所有 Web 控制項中的主版頁面設計、篩選器或其他功能。

  RenderContents

  最後,由於所需的 WebControl 類的方法和屬性都已被覆蓋,因此可以使用 RenderContents 方法來編寫文本。出於安全原因,MailLink 使用 HtmlTextWriter.WriteEncodedText 方法編寫 HTML 編碼輸出。HTML 編碼安全地將潛在的危險字元轉換為更安全的表示形式。

protected override void RenderContents(
 HtmlTextWriter writer) {
  if (Text == String.Empty) {
   Text = Email;
  }
  writer.WriteEncodedText(Text);
}
  請注意,我們只產生 Text 屬性。如果 Text 屬性為空白,我們將利用 Email 屬性填充它。請記住,Text 屬性旨在用作控制項標記的內部文本。這種類型的控制項至少需要某一可顯示的文本(以便使用者進行單擊)。如果我們試圖產生一個Null 字元串,我們將失去連結標記的預期功能。

  如何產生的?

  Render() 方法基本上控制著 WebControl 的整個輸出。預設情況下,Render() 方法實際上會依次調用 RenderBeginTag()、RenderContents() 以及 RenderEndTag()。儘管在 ASP.NET 1.x 中調用結構並未變化,但由於該呈現模型,修改這些調用的影響卻發生了變化。

  您可以覆蓋 Render() 方法來發出您想要的任何內容。換句話說,您可能已經跳過了覆蓋 TagKey 屬性、AttributestoRender 屬性和 RenderContents() 方法,並且僅使 Render() 編寫“text”。但是,這種做法可能會嚴重影響自適應呈現。如果重寫 Render() 來直接發出最終輸出,您會繞過內建到 WebControl 類中的大多數自適應呈現特性。

  自適應呈現模型和各種適配器的作用是:截獲對各種標記方法的調用並轉換特定裝置的輸出。在 MailLink 的特定樣本中,幾乎所有的標記語言都支援用於 連結的相同文法。但是,其他標記通常在不同的標記語言中會有截然不同的轉換。如果我們為這樣的標記使用了 Render(),我們的控制項將只能在某些瀏覽器上使用,而適配器無法更改該行為。通過設計控制項以使用自適應元素而不是使用 Render(),您可以讓 ASP.NET 架構有機會根據瀏覽器提供在瀏覽器上的呈現服務。

  使用自訂控制項

  自訂控制項能夠以很多方法包括在 Web 應用程式中。標準方法是將自訂控制項編譯到一個程式集中,然後在使用該控制項的所有 Web 應用程式中添加一個對該程式集的引用。

  使用 EmailLink

  為了使用 EmailLink 控制項,您需要:

  1.將 MyControls 項目編譯到一個程式集中。


圖 3. 編譯包含 EmailLink 控制項的 MyControls 命名空間
  2.在新的 Web 項目中添加一個對已編譯器集的引用。


圖 4. 編譯應用程式並添加一個引用
  在正確添加引用之後,自訂控制項應該出現在工具箱中的“MyControls Components”下。


圖 5. 工具箱中的 EmailLink
  MyControls 程式集中的所有組件都使用預設的齒輪表徵圖,因為我們未曾在每個控制項上設定特定的表徵圖。設定表徵圖如同在該控制項類上調整表徵圖屬性那樣簡單。


頁面上的控制項

  在添加了對包含控制項的程式集的引用之後,您可以將 MailLink 控制項拖動到設計器表面並像使用任何其他 ASP.NET 伺服器控制項那樣使用它。


圖 6. MailLink 自訂控制項
  圖 6 展示了 MailLink 控制項的設計器視圖。請注意,Properties 視窗公開了預期的 Email 和 Text 元素,它們可以用於配置控制項。通過將自訂控制項編譯到可重複使用的程式集中,MailLink 控制項可以被很多 Web 應用程式重複使用。

  建立複合伺服器控制項

  諸如 Login 和 GridView 這些可靠的控制項是由很多基本控制群組成的。在 ASP.NET 1.x 中,您必須通過艱苦的工作將嵌套標記和元素添加到自訂控制項中來開發複合控制項。在 ASP.NET 2.0 中,您可以通過擴充 System.Web.UI.WebControls.CompositeControl 類來構建複雜的複合控制項。CompositeControl 類提供了將多個控制項的輸出合并到單個統一的控制項中所必需的架構。

  管理複合控制項比管理基本自訂控制項稍微困難一些,因為複合控制項需要一些自訂布局的資訊。複合控制項將它們的呈現和事件處理任務委託給構成控制項。子組件的所有關聯的適配器類也會被自動應用。這樣,如果您具有適當的適配器,複合控制項將會在任何目標瀏覽器類型或裝置上正確地呈現。

  建立複合控制項

  建立複合控制項的初始過程與建立自訂伺服器控制項的初始過程相似。但是,該過程還涉及了更多的步驟。在以下樣本中,我們將建立一個由 Label 和 TextBox 組成的簡單的複合 AgeCollector 控制項,它旨在收集生日的資訊。

  複合控制項類應該通過從 CompositeControl 繼承開始。

public class AgeCollector : CompositeControl{}
  定義屬性

  對於我們的簡單控制項,我們必須為標籤 (Prompt) 和文字框 (DateOfBirth) 建立屬性。

[Bindable(true), Category("Appearance"),
DefaultValue("Please enter your date of birth:"),
Description("Text to prompt user with.")
Localizable(true)]
public virtual String Prompt {
 get
 {
  string s = (string)ViewState["Prompt"];
  return (s == null) ? String.Empty : s;
 }
 set {
  ViewState["Prompt"] = value;
 }
}
  再一次,我們使用特性為屬性提供說明和預設值。我們選擇了使提示可以進行本地化,以便該控制項無論何時都可以用於要求進行國際化的應用程式中。實際的提示可以綁定到包含語言特定文本的資源檔。

  還必須定義 DateOfBirth 屬性。但是,我們不是使用 String,而是使用 DateTime 資料類型來正確地儲存日期。

[Bindable(true), Category("Appearance"),
DefaultValue(""),
Description("Date of Birth Input area")]
public virtual DateTime DateOfBirth {
 get
 {
  bject o = ViewState["DateOfBirth"];
  return (o == null) ? DateTime.Now : (DateTime)o;
 }
 set {
  ViewState["DateOfBirth"] = value;
 }
}
  CreateChildControls 方法

  我們的複合控制項由一個標籤和一個文字框組成。我們無法使用簡單控制項的技術來顯示這兩個標記,除非使用強制方式和 Render() 方法。因為我們希望利用自適應呈現並顯示我們的兩個控制項,所以我們需要覆蓋內建到 CompositeControl 類中的 CreateChildControls() 方法。這種方法使我們可以定義控制項,並將我們的複合控制項的屬性傳遞到要顯示的單個控制項中。

protected override void CreateChildControls() {
 //Create and load the label
 Label lab1 = new Label();
 lab1.Text = Prompt;
 lab1.ForeColor = this.ForeColor;
 this.Controls.Add(lab1);

 //Add a line break between the label and text box
 Literal lit = new Literal();
 lit.Text = "";
 this.Controls.Add(lit);

 //Add the Textbox
 TextBox tb = new TextBox();
 tb.ID = "tb1";
 tb.Text = DateOfBirth.ToString();
 this.Controls.Add(tb);

 //call the parent method
 base.CreateChildControls();
}
  請注意,我們必須初始化每個控制項、分配所有屬性,然後將控制項添加到內建到 CompositeControl 類中的 Controls 集合。我們還使用了 Literal 對象將分行符號置於標籤和控制項之間。Literal 對象是非常簡單的控制項,您可以使用它在功能元素之間插入原始 HTML。

  請注意,我們還對基本方法進行了調用,以便確保我們的複合控制項具有內建到 CompositeControl 基類中的任何其他功能。尤其是,基本方法會強制 ASP.NET 將 Controls 集合的所有元素添加到控制項樹中。如果我們忽略這個調用,或者將其置於我們方法的頂部,那麼複合控制項將不會正確地產生。

  完整的 AgeCollector

  當我們的 AgeCollector 控制項產生時,ASP.NET 將在每個子控制項上實際調用適當的方法,並將結果合并到複合控制項的輸出中。換句話說,如果我們已正確地設計了簡單控制項,那麼該複合控制項就只是一個容器。自適應呈現模型將會自動應用到每個子控制項中。但是,實際的 CompositeControl 將不會被修改,因為它不包含需要更改的任何控制項。

  以下是另一個執行個體,其中使用的適當方法 (CreateChildControls()) 利用了自適應呈現模型,而不是簡單地在 WebControl 上重載 Render() 方法。由於自適應呈現模型和 CompositeControl 的特性,ASP.NET 2.0 節省了我們的開發時間、減少了程式碼數並減少了很多的測試煩惱。只要我們知道元素控制項可通過特定適配器正確地產生,CompositeControl 將會通過該適配器正確地產生。

  如果我們將控制項拖動到 ASP.NET 頁面上並查看屬性,我們將會看到具有 Prompt 和 DateOfBirth 屬性的單個控制項。


圖 7. AgeCollector 使用
  請注意,如果我們將複合控制項的 ForeColor 更改為紅色,我們實際上更改了 Label 的 ForeColor。但是,我們尚未連結某些其他屬性。例如,我們無法更改 DateOfBirth 欄位的 ForeColor。換句話說,當您構建一個複合控制項時,您始終需要考慮應該公開哪些子控制項屬性。



添加控制項行為

  到目前為止,我們設計的兩個控制項都是簡單、靜態控制項。也就是說,這些控制項不會完成利用普通的內建控制項或簡單使用者控制項 (.ascx) 無法完成的任何操作。構建自訂伺服器控制項的主要原因之一就是要提供使用現有控制項集無法執行的新功能。

  事件模型

  在 Web Form頁面中,與伺服器控制項關聯的事件由用戶端引發並由 Web 服務器處理。對於在客戶機上由伺服器控制項引發的事件,ASP.NET 2.0 事件模型收集有關請求的資訊,並使用 HTTP Post 將詳細資料傳遞到伺服器。伺服器上的 Page Framework 對該公告作出解釋以確定發生的事件,然後調用適當的處理常式方法。


圖 8. 典型的伺服器控制項事件
  ASP.NET 2.0 可處理幾乎所有捕獲、傳輸和解釋事件的方法。詳細資料對於開發人員來說是隱藏的,開發人員只需要關心伺服器上的處理常式方法的實現。

  大多數伺服器事件要求一個到伺服器的往返以便進行處理,因此支援有限數量的單擊類型事件。出於效能原因,不支援滑鼠移至上方和其他內部事件。

  回傳事件

  ASP.NET 2.0 中的很多伺服器控制項都產生回傳事件。回傳事件將頁面傳遞到伺服器以便進行處理。這是一個非常昂貴的操作,因為它要求頁面通過網路進行傳遞。

  回傳模型自從 ASP.NET 1.x 就沒有進行過顯著更改。為了建立一個可處理回傳的控制項,您的控制項必須實現 IPostBackDataHandler 介面,它定義了兩個方法:

  1) LoadPostData — 該方法處理您控制項的回傳資料。

  2) RaisePostDataChangedEvent — 該事件通知應用程式由於處理回傳資料,該控制項的狀態已經更改。

  PostDataChangedEvent 調用引發的事件必須在該控制項內部定義。然後,使用者可以在開發過程中編寫實際的事件方法。

  非回傳事件

  某些伺服器控制項支援非回傳事件。此類事件會更改控制項的狀態,但並不要求立即進行處理。這些事件由控制項緩衝,而不是立即傳遞到伺服器以進行處理。例如,ListBox 控制項可能包含很多元素。如果使用者選擇一個不同的元素,那麼控制項將在不通知伺服器的情況下顯示適當的更改並記住其新狀態。在張貼包含 ListBox 的表單之後,ListBox 控制項將提交事件(選定的項)。

  非回傳事件的預設行為可以通過設定 AutoPostBack 屬性變更。如果 AutoPostBack 設定為 true,那麼通常由用戶端緩衝的事件發送訊號通知伺服器立即進行處理。啟用 AutoPostBack 的控制項要求客戶機允許運行指令碼。

  ASP.NET 2.0 並未以任何明顯的方式更改該模型。

  回調和帶外請求

  標準的 Web 協議設計用於同步通訊。每個請求接收響應的速度與伺服器產生資料的速度同樣快。但是,很多任務都需要帶外 請求,例如同一時間訪問第三方資源。這些請求未處於瀏覽器和 Web 服務器之間的標準通訊帶區內,因此被認為是帶外請求。

  ASP.NET 1.x 中的帶外

  進行帶外資料請求的要求提示眾多開發人員可以創造性地使用可用資源來獲得所需的功能。例如,通過使用 ActiveX 組件和 JavaScript,開發人員能夠進行外部 HTTP 調用而無需完全回傳到伺服器。下面的 JavaScript 樣本說明了可以與 ASP.NET 1.x 一起使用的帶外 HTTP 要求。

function RetrieveGoogleFrontPage() {
 var XmlHttp = new ActiveXObject("Msxml2.XMLHTTP.4.0");
 XmlHttp.Open("GET", "http://www.fakedomain.com", false);
 XmlHttp.Send();
 return XmlHttp.responseText;
}
  這種機制的一個缺點就是 XmlHttp.responseText 包含該請求的完整結果。開發人員將必須編寫只返回商業資料的特殊頁面,否則響應會由於不必要的標記而非常龐大。

  ASP.NET 2.0 中的帶外

  ASP.NET 2.0 概括了 XmlHttp 對象的使用並提供了內建的回調功能。新系統的核心有兩個關鍵項:System.Web.UI.ICallbackEventHandler 和 Page.GetCallbackEventReference 方法。

  Page.GetCallbackEventReference 方法及其重載用於指定將參與回調事件的 JavaScript 方法。

public string GetCallbackEventReference(
 Control control,
 string argument,
 string clientCallback,
 string context
);
  上述代碼顯示了 GetCallBackEventReference 所需的最小參數集,這些參數將在下面進行詳細說明。

  Control — control 參數確定實現 RaiseCallbackEvent 方法的 ICallbackEventHandler。

  Argument — argument 字串包含用戶端指令碼。評估該指令碼的結果將作為 eventArgument 參數傳遞到 RaiseCallbackEvent。

  ClientCallback — clientCallback 參數包含用戶端事件處理常式的名稱,該處理常式將接收成功伺服器事件的結果。

  Context — context 參數包含一個用戶端指令碼。評估該指令碼的結果將傳遞到用戶端事件處理常式,該處理常式在 clientCallback 參數中指定為 context 參數。

  CallbackEventHandler 和 GetCallbackEventReference 方法相結合在用戶端和伺服器之間產生非同步通訊。


回調樣本

  以下 Web 頁使用回調機制查詢服務器以獲得其目前時間。該頁面彈出一個 JavaScript 警告,在無需完整頁面回傳的情況下顯示目前時間。

<%@ Page Language="C#" CompileWith="Default3.aspx.cs" ClassName="Default3_aspx" %>
<%@ Register TagPrefix="cc1" Namespace="MyControls" Assembly="WebControlLibrary3" %>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN" "http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">

<html xmlns="http://www.w3.org/1999/xhtml" >
<head runat="server">
<script language="javascript">
 function GetServerTime() {
  var message = '';
  var context = '';
  <%=CallBack%>
 }
 function ShowServerTime(timeMessage, context) {
  alert('The time on the server is:\n' + timeMessage);
 }
 function OnError(message, context) {
  alert('An unhandled exception has occurred:\n' + message);
 }
</script>
</head>
<body>
<form id="form1" runat="server">
 <div>
  <cc1:timesnap id="TimeSnap1" runat="server"> </cc1:timesnap>
  <input type="button" value="GetTime" /> 
 </div>
</form>
</body>
</html>
  上述頁面原始碼包含三個關鍵 JavaScript 函數:GetServerTime()、ShowServerTime() 和 OnError()。這些 JavaScript 函數與頁面的 GetCallbackEventReference 帶外請求相關聯。

public partial class Default3_aspx {
 public string CallBack;
 void Page_Load(object sender, EventArgs e) {
  CallBack = this.GetCallbackEventReference(TimeSnap1,"message","ShowServerTime","context","OnError");
 }
}
  GetCallbackEventReference 方法需要為其第一個參數實現 ICallbackEventHandler 介面的對象。通過實現 RaiseCallbackEvent() 方法,TimeSnap 自訂伺服器控制項符合介面要求。

public class TimeSnap : WebControl, ICallbackEventHandler
{
 ...
 public string RaiseCallbackEvent(string eventArgument) {
  // Uncomment next line to test error handler
  // throw new ApplicationException(// "Some unhandled exception");
  return DateTime.Now.ToLocalTime().ToShortTimeString();
 }
}
}
  TimeSnap.RaiseCallbackEvent() 方法僅返回 string 格式的目前時間。


圖 9. 回調請求輸出
  圖 9 說明了按下 GetTime 按鈕的結果。向伺服器發出帶外請求,從而產生顯示伺服器上目前時間的“Alert”視窗。發出這個請求不需要回傳,因此控制項的最初產生時間不會改變。

  使用設計器

  在前面的樣本中,我們已經使用了幾個標準的特性來規定自訂控制項的屬性將與設計器 (Visual Studio) 進行互動的方式。我們為各種控制項屬性分配了特性以定義屬性將在其中出現的類別、定義屬性是否應該具有一個預設值、定義屬性的說明應該是什麼樣子以及屬性是否應該為 bindable。在 ASP.NET 1.x 中,附加的設計器類 使您可以建立用於編輯屬性的新對話方塊、自動將屬性值從 String 轉換為其他資料類型(反之亦然),並顯示只在運行時產生的控制項的預留位置資料。

  設計器類有助於將控制項開發分成兩個階段。第一,您必須開發自訂控制項。第二,您必須決定開發人員將如何與設計環境內的控制項進行互動。設計器類通過在每個自訂控制項的頂部充當裝飾師來完成第二個任務。換句話說,如果您要開發很多自訂控制項,您可以建立一個標準的可重複使用的設計器集,並通過特性簡單地將設計器應用到每個自訂控制項中。

  ASP.NET 2.0 為設計器模型提供了幾項增強功能:

  1) 新的複合控制項設計器 — CompositeControlDesiger 類完全識別複合控制項,並且提供支援父子控制項關係的功能。

  2) 新的資料繫結控制項設計器 — DataBoundControlDesigner 為 Databound 控制項提供了很多新功能。您可以使用該設計器來提供類比資料,或者在設計期間自動連接到活 datasource。

  3) 增強備用設計時地區支援 — 新的 DesignerRegion 類及其子類提供了一種非常靈活的機制以便顯示控制項。您可以使用 DesignerRegion 來設定控制項的選項卡式視圖。您還可以使用 EditableDesignerRegion 控制項為控制項建立新的模板。

  4) 增強模板支援 — 現在,設計器類提供了更簡潔的機制以便將新的模板添加到控制項中。樣板化控制項是一種將控制項邏輯和控制項顯示分開的控制項。顯示通過模板進行定義,而邏輯在實際控制項中進行編碼。

  5) 增強任務支援 — 現在,設計器可以合并設計時的任務。最常見的任務將可在視圖之間切換。但是,其他任務可以包括控制項的自動設定或資源檔的自動建立。任務可以在設計階段控制項 (DTC)上顯示為菜單(與允許您配置 GridView 控制項的菜單相似)。

  6) 增強事件支援 — 設計器中的事件模型已經進行了改進。現在,您可以建立事件來響應在不同地區中的單擊或對各種任務的單擊。使用設計器時,只要使用者在特定地區上單擊就可以使控制項切換視圖、自動產生代碼或更改配置。

  ASP.NET 2.0 具有一個經過顯著改進的設計器模型,它可以使專業控制項開發人員的工作更加簡單。如果您只是為自己使用而構建一個單個的控制項,該設計器就大材小用了。但是,如果您要為分發而構建一個控制項,您可以使用新的設計器來全面地自訂 Visual Studio 2005 中控制項的行為。

  小結

  儘管 ASP.NET 2.0 包含了一個內容豐富的擴充控制項集,但開發人員通常有很多理由來建立自訂控制項。由於 ASP.NET 2.0 中的增強功能,建立自訂控制項的過程要比在 ASP.NET 1.x 中更快、更容易。新的 CompositeControl 基類完全利用自適應呈現模型,並為建立複雜的控制項提供了一個簡單、便於使用的容器。如果您的控制項需要回傳或回調功能,ASP.NET 2.0 簡化了處理用戶端指令碼檔案和開發帶外請求的過程。最後,在您開發控制項後,您可以使用各種設計器類來完全配置控制項在視覺化設計工具(例如 Visual Studio 2005)內的行為。



聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.