ASP.NET服務(wù)器控件之RenderContents應(yīng)用示例
ASP.NET服務(wù)器控件之RenderContents應(yīng)用示例
相信讀者在瀏覽各個(gè)網(wǎng)站時(shí),經(jīng)常會(huì)看到"聯(lián)系我們"等類似文字。當(dāng)單擊這些文字時(shí),操作系統(tǒng)將自動(dòng)打開自身所帶的郵件客戶端軟件,提示用戶發(fā)送郵件。本例將實(shí)現(xiàn)一個(gè)自定義服務(wù)器控件RenderContentsControl,其用于通過呈現(xiàn)包含"mailto:郵件地址"的超鏈接。本例的示例效果圖如圖1所示:
如圖1所示,頁(yè)面中呈現(xiàn)了超鏈接文字"我的郵箱地址"。當(dāng)單擊該鏈接,系統(tǒng)將發(fā)送郵件給"my@mysample.com"。
在實(shí)現(xiàn)以上ASP.NET服務(wù)器控件之前,首先應(yīng)分析如下:本控件包含外觀元素,例如,文字大小、顏色、是否粗體等。為此,控件基類不應(yīng)從Control類繼承,而應(yīng)從WebControl類繼承。這樣,開發(fā)人員將不必自行實(shí)現(xiàn)這些外觀樣式屬性等內(nèi)容。
下面列舉了實(shí)現(xiàn)自定義服務(wù)器控件的RenderContentsControl.cs文件源代碼。
- using System;
- using System.ComponentModel;
- using System.Security;
- using System.Security.Permissions;
- using System.Web;using System.Web.UI;
- using System.Web.UI.WebControls;
- namespace UsingRenderContentsControl{
- [
- AspNetHostingPermission(SecurityAction.Demand,
- Level = AspNetHostingPermissionLevel.Minimal),
- AspNetHostingPermission(SecurityAction.InheritanceDemand,
- Level = AspNetHostingPermissionLevel.Minimal),
- DefaultProperty("Email"), ParseChildren(true, "Text"),
- ToolboxData("﹤{0}:RenderContentsControl runat=server﹥﹤/{0}:RenderContentsControl﹥")
- ]
- public class RenderContentsControl : WebControl {
- // 實(shí)現(xiàn)Email屬性
- [Bindable(true)]
- [Category("Appearance")]
- [DefaultValue("")] [Localizable(true)]
- public string Email
- {
- get {
- String s = (String)ViewState["Email"];
- return ((s == null) ? String.Empty : s);
- }
- set {
- ViewState["Email"] = value;
- }
- }
- // 實(shí)現(xiàn)Text屬性
- [
- Bindable(true), Category("Appearance"), DefaultValue(""), 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;
- }
- }
- // 重寫TagKey屬性
- protected override HtmlTextWriterTag TagKey
- {
- get {
- return HtmlTextWriterTag.A;
- }
- }
- // 重寫AddAttributesToRender方法
- protected override void AddAttributesToRender(HtmlTextWriter writer)
- {
- base.AddAttributesToRender(writer);
- writer.AddAttribute(HtmlTextWriterAttribute.Href, "mailto:" + Email);
- }
- // 重寫RenderContents方法
- protected override void RenderContents(HtmlTextWriter writer)
- {
- if (Text == String.Empty) {
- Text = Email;
- }
- writer.WriteEncodedText(Text);
- }
- }
- }
如上代碼所示,RenderContentsControl類繼承自WebControl基類,其原因在前文已經(jīng)說明。另外,在RenderContentsControl類的實(shí)現(xiàn)過程中,還包括了元數(shù)據(jù)屬性標(biāo)記、3個(gè)屬性(Email、Text和TagKey)和2兩個(gè)方法(AddAttributesToRender和RenderContents)實(shí)現(xiàn)等內(nèi)容。下面逐一對(duì)這些內(nèi)容進(jìn)行分析。
代碼說明之3個(gè)屬性:
在上文代碼中主要包括了3個(gè)屬性:Email、Text和TagKey。Email屬性用于獲取或者設(shè)置具體的電子郵件地址,Text屬性用于獲取或者設(shè)置控件顯示的文本內(nèi)容。在這兩個(gè)屬性實(shí)現(xiàn)中,都使用了控件視圖狀態(tài)ViewState。ASP.NET服務(wù)器控件的視圖狀態(tài)為其所有屬性值的累計(jì)。對(duì)于簡(jiǎn)單屬性的實(shí)現(xiàn),將經(jīng)常使用ViewState。TagKey屬性是重寫屬性,其繼承自WebControl基類,這是讀者需要理解的重點(diǎn)內(nèi)容。重寫TagKey屬性主要是為了呈現(xiàn)HTML標(biāo)記中的a元素,這樣就不會(huì)呈現(xiàn)WebControl類所默認(rèn)呈現(xiàn)的span元素。此處,也暗示了本控件使用的構(gòu)造函數(shù)是繼承自WebControl的protected WebControl (),讀者可返回上文再看看有關(guān)這個(gè)構(gòu)造函數(shù)的說明。需要讀者牢記的是:如果要呈現(xiàn)的元素是HtmlTextWriterTag枚舉的成員,則應(yīng)重寫TagKey屬性。許多常見的HTML元素標(biāo)記被映射為HtmlTextWriterTag枚舉的值。例如,System.Web.UI.HtmlTextWriterTag.A與a元素對(duì)應(yīng),而System.Web.UI.HtmlTextWriterTag.Table與table元素對(duì)應(yīng)。如果要呈現(xiàn)的元素不是由HtmlTextWriterTag枚舉的成員表示,那么建議重寫TagName屬性,并返回要作為元素呈現(xiàn)的字符串。
代碼說明之2個(gè)方法:
在RenderContentsControl服務(wù)器控件中重寫了2個(gè)重要方法:一個(gè)是AddAttributesToRender、另一個(gè)是RenderContents。
(1)AddAttributesToRender
該方法用于為ASP.NET服務(wù)器控件添加一個(gè)Href屬性,并將該屬性值設(shè)置為"mailto:Email",其中Email是上文所述的表示郵件地址的屬性。當(dāng)重寫AddAttributesToRender方法時(shí),應(yīng)始終按照控件源代碼演示的方式:首先,調(diào)用基類方法,然后進(jìn)行相關(guān)設(shè)置。這樣才能實(shí)現(xiàn)為服務(wù)器控件添加樣式和其他屬性的功能。實(shí)際上,根據(jù)前文所述的RenderBeginTag方法的實(shí)現(xiàn)示意性代碼可知,AddAttributesToRender方法是由WebControl的RenderBeginTag方法調(diào)用。
(2)RenderContents
該方法是本示例的核心內(nèi)容,其用于在ASP.NET服務(wù)器控件的標(biāo)記中寫入由Text屬性指定的超鏈接文本。如代碼所示,服務(wù)器控件調(diào)用了HtmlTextWriter實(shí)例的WriteEncodedText方法,以對(duì)開發(fā)人員輸入的文本進(jìn)行HTML編碼。一般情況下,為了安全起見,應(yīng)該對(duì)用戶提供的文本進(jìn)行HTML編碼。
代碼說明之元數(shù)據(jù)屬性標(biāo)記:
元數(shù)據(jù)屬性標(biāo)記在類前和屬性實(shí)現(xiàn)前都有所應(yīng)用。有關(guān)這些元數(shù)據(jù)屬性標(biāo)記的說明,在以前的文章中已經(jīng)進(jìn)行了具體說明。讀者可查閱有關(guān)講解如何創(chuàng)建一個(gè)簡(jiǎn)單的服務(wù)器控件的文章。下面重點(diǎn)說明一下有關(guān)內(nèi)部文本持久性的問題。
在類前的元數(shù)據(jù)屬性標(biāo)記中,設(shè)置了ParseChildren(true, "Text")。在Text屬性前的元數(shù)據(jù)屬性標(biāo)記中,設(shè)置了PersistenceMode(PersistenceMode.InnerDefaultProperty)。通過以上兩個(gè)設(shè)置,則為控件添加了內(nèi)部文本持久性設(shè)置。如此設(shè)置,可使得開發(fā)人員能夠在控件標(biāo)記代碼內(nèi)設(shè)置Text屬性。例如:
﹤Sample:RenderContentsControl runat="server" ID="CustomerControl" Email="my@mysample.com"﹥我的郵箱地址﹤/Sample:RenderContentsControl﹥
在上面的代碼中,原來文本"我的郵箱地址"應(yīng)由Text屬性設(shè)置(這就是默認(rèn)持久性),然而,由于內(nèi)部文本持久性設(shè)置,因此,可以在控件標(biāo)記內(nèi)設(shè)置控件文本。
實(shí)現(xiàn)內(nèi)部持久性,應(yīng)使用ParseChildren(true, "Text")來標(biāo)記RenderContentsControl控件。ParseChildren的***個(gè)參數(shù)true,其用于指定頁(yè)分析器應(yīng)將控件標(biāo)記內(nèi)的內(nèi)容分析為屬性,而不是子控件。第二個(gè)參數(shù)提供控件的內(nèi)部默認(rèn)屬性名稱為Text。使用這兩個(gè)參數(shù)調(diào)用ParseChildren構(gòu)造函數(shù)時(shí),控件標(biāo)記內(nèi)的內(nèi)容必須與內(nèi)部默認(rèn)屬性對(duì)應(yīng)。Text屬性的PersistenceMode(PersistenceMode.InnerDefaultProperty),用于指定可視化設(shè)計(jì)器應(yīng)將此屬性作為控件標(biāo)記中的內(nèi)部?jī)?nèi)容進(jìn)行序列化。
通常,WebControl類使用PersistChildren(false)和ParseChildren(true)控制設(shè)計(jì)時(shí)和分析時(shí)屬性的持久性。這兩個(gè)屬性將被控件繼承,且僅在要更改繼承的設(shè)置時(shí)需要應(yīng)用。PersistChildren告知設(shè)計(jì)器是否應(yīng)將ASP.NET服務(wù)器控件的子控件作為嵌套的內(nèi)部控件保存。false參數(shù)指示內(nèi)部?jī)?nèi)容與屬性對(duì)應(yīng),而不是與子控件對(duì)應(yīng)。ParseChildren已在上一段中加以說明。如果WebControl類的設(shè)計(jì)時(shí)和分析時(shí)持久性適用于您的控件,則不必重寫從WebControl繼承的PersistChildren和ParseChildren。
下面列舉了用于測(cè)試服務(wù)器控件的Default.aspx文件源代碼:
- ﹤%@ Page Language="C#" AutoEventWireup="true"
- CodeFile="Default.aspx.cs" Inherits="_Default" %﹥
- ﹤%@ Register TagPrefix="Sample"
- Assembly="UsingRenderContentsControl" Namespace="UsingRenderContentsControl" %﹥
- ﹤!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 id="Head1" runat="server"﹥
- ﹤title﹥使用RenderContents方法實(shí)現(xiàn)控件呈現(xiàn)﹤/title﹥
- ﹤/head﹥
- ﹤body﹥
- ﹤form id="form1" runat="server"﹥
- ﹤div﹥
- ﹤Sample:RenderContentsControl runat="server"
- ID="CustomerControl" Font-Bold="true" Font-Size="small"
- ForeColor="Blue" Email="my@mysample.com"﹥我的郵箱地址﹤/Sample:RenderContentsControl﹥
- ﹤/div﹥
- ﹤/form﹥
- ﹤/body﹥
- ﹤/html﹥
如上粗體代碼所示,RenderContentsControl控件中設(shè)置了Font-Bold、Font-Size、ForeColor、Email等屬性,同時(shí),還在控件標(biāo)記之間設(shè)置了文本內(nèi)容。當(dāng)然,如果開發(fā)人員將Text屬性值設(shè)置為相同的文本內(nèi)容也是可以的。以上代碼比較簡(jiǎn)單,在此不再說明了。
通過這個(gè)示例,我們需要重點(diǎn)掌握RenderContents和AddAttributesToRender方法,以及TagKey屬性的使用。提請(qǐng)讀者注意的是雖然服務(wù)器控件的代碼比較復(fù)雜,但是結(jié)構(gòu)很簡(jiǎn)單。切不可被復(fù)雜的樣式設(shè)置和客戶端行為代碼弄得不知所措,而是要注意體會(huì)兩個(gè)重點(diǎn)方法的使用過程。
在服務(wù)器控件開發(fā)成功之后,***能夠查看其HTML代碼,并將服務(wù)器代碼和HTML代碼作以比較,搞清楚每一條ASP.NET服務(wù)器控件代碼呈現(xiàn)了什么樣的HTML代碼。通過這個(gè)方法,相信讀者能夠?qū)SP.NET服務(wù)器控件的呈現(xiàn)方法有更加深刻的體會(huì)。下面列舉了當(dāng)用戶在瀏覽器中運(yùn)行以上頁(yè)面,并查看相關(guān)的Html源文件時(shí)可得到的代碼:
- ﹤!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 id="Head1"﹥
- ﹤title﹥ 使用RenderContents方法實(shí)現(xiàn)控件呈現(xiàn)﹤/title﹥
- ﹤/head﹥
- ﹤body﹥
- ﹤form name="form1" method="post" action="Default.aspx" id="form1"﹥
- ﹤div﹥
- ﹤input type="hidden" name="__VIEWSTATE" id="__VIEWSTATE"
- value="/wEPDwULLTEyNTQwNjQyMDJkZOlJ3PyMGs2hmzn9MU6Ogt9V+5ag" /﹥
- ﹤/div﹥
- ﹤div﹥
- ﹤a id="CustomerControl" href="mailto:my@mysample.com"
- style="color:Blue;font-size:Small;font-weight:bold;"﹥我的郵箱地址﹤/a﹥
- ﹤/div﹥
- ﹤/form﹥
- ﹤/body﹥
- ﹤/html﹥
通過觀察以上代碼可知,自定義服務(wù)器控件RenderContentsControl實(shí)際呈現(xiàn)的結(jié)果是粗體所示部分的代碼,其最終呈現(xiàn)為一個(gè)表示超鏈接的﹤a﹥標(biāo)記,其中包括href、Style和文本等屬性值。它們的值與Default.aspx文件源代碼中,RenderContentsControl控件的屬性設(shè)置有著密切關(guān)系。例如,Email屬性值最終呈現(xiàn)為href屬性值等等。讀者可自行對(duì)照查看,這對(duì)于理解控件呈現(xiàn)很有益處。
小結(jié)
本文主要介紹了WebControl類的一些基本知識(shí),并且利用這些基本知識(shí)創(chuàng)建了一個(gè)簡(jiǎn)單的控件呈現(xiàn)實(shí)例。實(shí)際上,從中讀者應(yīng)該能夠總結(jié)出來,創(chuàng)建繼承自WebControl基類的自定義服務(wù)器控件,其中最為重要的重寫RenderContents方法。記住這一點(diǎn)是非常重要的。至此,筆者已經(jīng)利用兩篇文章來介紹實(shí)現(xiàn)控件呈現(xiàn)的方法。在以后的文章中,將介紹有關(guān)為ASP.NET服務(wù)器控件實(shí)現(xiàn)屬性等方面的內(nèi)容。
ASP.NET服務(wù)器控件之RenderContents應(yīng)用示例的相關(guān)內(nèi)容就向你介紹到這里,希望你能了解ASP.NET服務(wù)器控件之RenderContents的應(yīng)用。【編輯推薦】
- ASP.NET服務(wù)器控件開發(fā)之實(shí)現(xiàn)事件淺析
- ASP.NET服務(wù)器控件之處理回傳數(shù)據(jù)淺析
- ASP.NET服務(wù)器控件之捕獲回傳事件淺析
- ASP.NET控件開發(fā)基礎(chǔ)之事件處理淺析
- ASP.NET服務(wù)器控件之RenderContents簡(jiǎn)介