top
Loading...
ASP.NET2.0服務器控件之創建自定義控件
友情推薦:ASP.NET初學者入門最佳實踐

下載本文源代碼

摘要

本文將詳細講解一個簡單的自定義服務器控件的創建過程。通過這些內容,讀者將了解利用Visual Studio 2005,創建和測試自定義服務器控件的基本方法。

注意:本文內容基于ASP.NET 2.0技術撰寫,示例應用程序使用Visual Studio 2005進行開發。

創建一個簡單的自定義服務器控件

創建自定義服務器控件的過程包括:

(1)創建一個測試用Web站點應用程序;
(2)為新建站點應用程序,新增一個Web控件庫項目;
(3)編寫、編譯和測試自定義服務器控件。

(1)創建一個測試用Web站點應用程序

利用Visual Studio 2005,創建Web站點應用程序的方法很多,例如,在本地文件系統中創建、在IIS支持下創建、在FTP站點中創建、在遠程站點中創建等等。然而,無論如何,開發人員都應首先打開Visual Studio 2005,然后,單擊"文件"菜單下"新建網站..."項目。這時,將彈出如下圖1的對話框。

點擊放大此圖片
圖1 新建網站對話框

圖1是新建網站對話框。在該對話框中,開發人員需要選擇創建模板,位置、編程語言。如圖1所示,示例采用了ASP.NET網站模板,文件系統和C#編程語言來創建。當單擊"確定"按鈕之后,Visual Studio 2005將在本機D:AppTest下創建一個test1文件夾。所有應用程序文件都存儲在文件夾內。默認情況下,test1文件夾內包括一個空的用于存儲應用程序數據文件的App_Data文件夾,同時還分別包括一個Default.aspx和Default.aspx.cs文件。

通過以上步驟就創建了一個Web站點應用程序。該Web站點將用于測試所創建的Web自定義服務器控件。

(2)新增自定義服務器控件項目

在創建Web站點應用程序之后,開發人員還必須在當前站點項目中,添加一個自定義服務器控件項目,也就是Web控件庫項目。實現方法是:在打開Web站點應用程序的前提下,單擊"文件"菜單中"添加"項的子項"新建項目"。此時,Visual Studio 2005將彈出如圖2的對話框。

點擊放大此圖片
圖2 添加新項目對話框

圖2是添加新項目對話框截圖。該對話框分為三個設置部分:項目類型、模板、名稱和位置。

在對話框左側有一個樹形列表,其中包括各種項目類型。為創建Web控件庫項目,應選擇"Visual C#"節點的子節點"Windows"。此時,對話框右側將出現該子節點對應的已安裝模板,其中包括Windows應用程序、類庫、Web控件庫等。開發人員應選中"Web控件庫"一項。最后,需要設置Web控件庫項目的名稱和位置。為了便于管理,建議將Web控件庫項目和測試站點項目存儲在同一文件夾內,因此,本例將名稱設置為"HelloMyControl",將位置設置為D:AppTestest1。當單擊"確定"按鈕之后,Visual Studio 2005將在D:AppTestest1目錄下,自動創建一個HelloMyControl用于存儲Web控件庫相關文件。同時,Visual Studio 2005的"解決方案資源管理器"將顯示如圖3所示內容。


圖3 解決方案資源管理器

如圖3所示,解決方案資源管理器中包括兩個項目。一個是前文創建的Web站點項目,另一個是名為HelloMyControl的Web控件庫項目,其中默認包括一個WebCustomControl1.cs文件。下面就可以開始編寫、編譯和測試自定義服務器控件了。

(3)編寫、編譯和測試自定義服務器控件

需要實現的自定義服務器控件WelcomeLabel功能很簡單。類似于一個標準Label控件。WelcomeLabel控件從System.Web.UI.WebControls. WebControl繼承,其中自定義了一個string類型的Text屬性。當控件運行時,將顯示Text屬性值和當前用戶名的組合文字。例如,將Text屬性值設置為"您好",那么最終顯示的是"您好,某某!"。開發人員可以用WelcomeLabel控件作為站點歡迎頁面的一部分。

WelcomeLabel控件的實現代碼包含在WebCustomControl1.cs文件中。該文件源代碼如下所示。

using System;
using System.Collections.Generic;
using System.Security.Permissions;
using System.ComponentModel;
using System.Text;
using System.Web;
using System.Web.UI;
using System.Web.UI.WebControls;
namespace HelloMyControl
{
[
AspNetHostingPermission (SecurityAction.Demand, Level = AspNetHostingPermissionLevel.Minimal ),
AspNetHostingPermission (SecurityAction.InheritanceDemand, Level = AspNetHostingPermissionLevel.Minimal ),
DefaultProperty ( "Text" ),
ToolboxData ( "<{0}:WelcomeLabel runat="server" > </{0}:WelcomeLabel>")
]
public class WelcomeLabel : WebControl
{
// 實現Text屬性
[
Bindable(true), Category("Appearance"), DefaultValue(""), Description("文本內容."), Localizable(true)
]
public virtual string Text
{
get
{
string s = (string)ViewState["Text"];
return (s == null) ? String.Empty : s;
}
set
{
ViewState["Text"] = value;
}
}
// 重寫RenderContents方法
protected override void RenderContents(HtmlTextWriter writer)
{
// 對Text屬性值編碼,并寫入輸入流中
writer.WriteEncodedText(Text);
// 判斷Web請求是否有效。如果有效,則設置內容,并寫入輸出流中
if (Context != null)
{
// 獲取當前用戶名
string s = Context.User.Identity.Name;
// 如果當前用戶名不為空,則分析用戶名并按照指定格式寫入輸出流中
if (s != null && s != String.Empty)
{
string[] split = s.Split('\');
int n = split.Length - 1;
if (split[n] != String.Empty)
{
writer.Write(",");
writer.Write(split[n]);
}
}
}
writer.Write("!");
}
}
}

代碼說明之控件基類:

如果服務器控件需要呈現用戶界面(UI)元素或任何其他客戶端可見的元素,則應該從System.Web.UI.WebControls.WebControl(或派生類)派生該控件。如果控件要呈現在客戶端瀏覽器中不可見的元素(如隱藏元素或meta元素),則應從System.Web.UI.Control派生該控件。本例顯然需要呈現用戶界面元素,因此,自定義服務器控件類WelcomeLabel從WebControl基類繼承。由于WebControl類從Control派生,因此,WelcomeLabel控件則自動繼承基類提供的成員對象,這些對象多數與用戶界面元素呈現有關,例如,Font、ForeColor、BackColor、Width等等。另外,同樣也是由于從WebControl繼承,因此,WelcomeLabel控件還自動實現ASP.NET 2.0新增的主題和皮膚功能。實際上,由于WelcomeLabel控件與ASP.NET 2.0的內置服務器控件Label有著很多相似之處,因此,從功能實現的角度出發,最好的方式應該是使得WelcomeLabel控件類從Label類繼承。然而,本例為了說明定義屬性和定義屬性元數據的實現方法,因此,從WebControl基類繼承。

代碼說明之Text屬性:

如上源代碼所示,WelcomeLabel實現了一個Text屬性,并使用視圖狀態存儲該屬性值。使用視圖狀態保存回發間的Text值。每次回發時,將重新創建頁并從視圖狀態還原值。如果Text值并未存儲在視圖狀態中,則在每次回發時會將值設置為其默認的Empty。ViewState屬性繼承自WebControl,是保存數據值的字典。通過使用String鍵,可輸入和檢索值。本例中將"Text"用作鍵。字典中的項被類型化為Object,然后必須將其強制轉換為屬性類型。

代碼說明之RenderContents方法:

通常,在從WebControl派生控件并呈現單個元素時,應重寫RenderContents方法(而不是Render方法),以呈現控件標記中的內容。在呈現控件及其樣式屬性的開始標記之后,WebControl的Render方法將調用RenderContents。如果重寫Render方法以寫入內容,則控件將丟失生成到WebControl的Render方法中的樣式呈現邏輯。

在源代碼中,WelcomeLabel控件重寫了繼承的RenderContents方法以呈現Text屬性及其他一些內容。傳入RenderContents方法的參數是HtmlTextWriter類型的對象,它是具有呈現標記和其他HTML(和HTML變量)標記的方法的實用工具類。可能讀者已經注意到:WelcomeLabel連續調用了HtmlTextWriter對象的Write方法,而不是先執行字符串串聯,然后調用Write方法。這種做法可提高控件性能。字符串串聯需要時間和內存來創建字符串,然后寫入流。

代碼說明之元數據屬性標記:

如上代碼所示,在WelcomeLabel類聲明前包括以下3個元數據屬性標記。

(1)AspNetHostingPermissionAttribute

它是代碼訪問安全屬性。該屬性使JIT編譯器檢查鏈接到WelcomeLabel的代碼是否具有AspNetHostingPermission權限。所有的公共ASP.NET類均使用此屬性標記。應將AspNetHostingPermissionAttribute應用于控件,以對部分受信任的被調用方進行安全檢查。

(2)DefaultPropertyAttribute

它是設計時屬性(Attribute),它指定控件的默認屬性(Property)。在可視化設計器中,當頁開發人員在設計圖面上單擊控件時,屬性瀏覽器通常突出顯示此默認屬性。

(3)ToolboxDataAttribute

它用于指定元素的格式字符串。如果在工具箱中雙擊控件或將其從工具箱拖動到設計圖面上時,該字符串將成為控件的標記。對于WelcomeLabel,該字符串創建此元素:

<aspSample:WelcomeLabel runat="server"> </aspSample:WelcomeLabel>

另外,在屬性Text的實現過程中還定義了以下元數據屬性。

(1)BindableAttribute(被指定為true或false)

該元數據屬性可用于指定將屬性綁定到數據對可視化設計器是否有意義。例如,在VisualStudio2005中,如果屬性標記為Bindable(true),則該屬性可顯示在"數據綁定"對話框中。如果屬性(Property)沒有使用此屬性(Attribute)標記,則屬性(Property)瀏覽器會推斷其值為Bindable(false)。

(2)CategoryAttribute

該元數據屬性用于指定如何在可視化設計器的屬性瀏覽器中對屬性進行分類。例如,當頁開發人員使用屬性瀏覽器的分類視圖時,Category("Appearance")將告知屬性瀏覽器在"外觀"類別中顯示屬性。可以根據屬性瀏覽器中的現有類別指定字符串參數,也可以創建自己的類別。

(3)DescriptionAttribute

該元數據屬性用于指定屬性的簡短描述。在VisualStudio2005中,屬性瀏覽器將在"屬性"窗口底部顯示選定的屬性的描述。

(4)DefaultValueAttribute

該元數據屬性用于指定屬性的默認值。此值應與從屬性訪問器(getter)返回的默認值相同。在VisualStudio2005中,DefaultValueAttribute允許頁開發人員通過在"屬性"窗口中喚出快捷菜單然后單擊"重置"按鈕將屬性值重置為其默認值。

(5)LocalizableAttribute(指定為true或false)

該元數據屬性用于指定本地化屬性對可視化設計器是否有意義。當某屬性標記為Localizable(true)時,可視化設計器會在對本地化資源進行序列化時包含該屬性。對控件輪詢可本地化的屬性時,設計器會將此屬性值保存到非特定于區域性的資源文件或其他本地化源中。

在編寫完成WelcomeLabel控件的源代碼之后,接著需要編譯和測試所實現的自定義服務器控件。為了實現這一目的,開發人員需要在測試用Web站點中引用Web控件庫項目輸出,并編寫相關代碼以便測試服務器控件。

在Web站點中實現Web控件庫項目引用的方法比較簡單。首先,右鍵單擊解決方案資源管理器中的Web站點項目名稱,在彈出的菜單中選中"添加引用..."一項。此時,將自動彈出如圖4所示的窗口。


圖4 添加引用對話框

如圖4所示,在添加引用窗口中包括5個選項卡,其中包括一個名為"項目"的選項卡。單擊它可發現在其列表中包括一個上文創建的HelloMyControl項目。選中該項并單擊"確定"按鈕,即可完成項目引用。

在完成項目引用后,Visual Studio 2005將自動在Web站點項目中添加一個Bin文件夾,并在其中包含了HelloMyControl.dll和HelloMyControl.pdb文件。前者是控件程序集,后者中則保存著調試和項目狀態信息。這樣,Web站點就能夠順利使用HelloMyControl項目的輸出了。如下顯示了為測試WelcomeLabel控件而創建的Default.aspx文件源代碼。

<%@ Page Language="C#" AutoEventWireup="true" CodeFile="Default.aspx.cs" Inherits="_Default" %>
<%@ Register TagPrefix="self" Namespace="HelloMyControl" Assembly="HelloMyControl" %>
<!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>
<self:WelcomeLabel Text="您好" ID="WelcomeLabel1" runat="server" BackColor="Wheat" ForeColor="SaddleBrown" />
</div>
</form>
</body>
</html>

如上粗體代碼所示,頁面首先利用@ Register指令將WelcomeLabel控件引入,然后,通過<self:WelcomeLabel>標記具體指示控件的位置,以及屬性設置等。在<self:WelcomeLabel>標記中,主要設置了Text、BackColor和ForeColor屬性,它們分別用于定義控件的文本內容、背景顏色和前景顏色。

如圖5顯示了執行Default.aspx的頁面截圖。


圖5 示例應用程序截圖

小結

本文通過一個簡單示例說明了實現自定義服務器控件的基本過程。通過這些內容,讀者可能已經發現:創建自定義服務器控件與創建普通Web應用程序之間有著較大區別,這些差別主要體現在創建模式、所利用技術等方面。在隨后的系列文章中,將詳細探討利用ASP.NET 2.0技術創建自定義服務器控件的相關內容。

作者:http://www.zhujiangroad.com
來源:http://www.zhujiangroad.com
北斗有巢氏 有巢氏北斗