ASP.NET2.0伺服器控制元件之Render方法

NO IMAGE

  控制元件呈現是指向HTTP輸出流中寫入標記文字的過程。伺服器通過HTTP輸出流向客戶端傳送生成的標記文字,這些文字將會通過客戶端瀏覽器轉換為視覺化的元素顯示出來。使用控制元件呈現,開發人員可以將HTML標記、指令碼程式碼、CSS樣式表等等輸入到客戶端瀏覽器。實現伺服器控制元件呈現主要有兩種方式:一是Control類的Render方法,二是WebControl的RenderContents方法。本文重點介紹使用Control類的Render方法實現控制元件呈現的應用。

  使用HtmlTextWriter類

  Control類的Render方法主要用於實現控制元件呈現,其宣告程式碼如下:

protected virtual void Render(HtmlTextWriter output)

  如上程式碼所示,Render方法的引數是一個HtmlTextWriter型別。為了更好的應用Render方法,讀者應首先了解HtmlTextWriter類及其相關內容。

  根據MSDN2005的描述,HtmlTextWriter類用於將標記字元和文字寫入到ASP.NET伺服器控制元件輸出流。此類提供了ASP.NET伺服器控制元件在向客戶端呈現標記時所使用的格式設定功能。為了實現類的功能,HtmlTextWriter類定義了多個欄位、屬性和方法。由於成員物件眾多,本文只挑選了一些常用成員加以說明,同時,還將介紹一些ASP.NET 2.0的新增成員。

  常用成員物件包括:

  ·AddAttribute方法

  對於HtmlTextWriter物件通過對RenderBeginTag方法的後續呼叫建立的元素,向其開始標記中新增指定的標記屬性和值。

  ·AddStyleAttribute方法

  對於 HtmlTextWriter 物件通過對 RenderBeginTag 方法的後續呼叫建立的元素,向其開始標記中新增標記樣式屬性。

  ·Write方法

  將指定資料型別連同任何掛起的製表符間距一起寫入到輸出流。

  ·WriteAttribute方法

  將標記屬性及其值寫入到輸出流。

  ·WriteBeginTag方法

  任何製表符間距和指定標記元素的開始標記寫入到輸出流。

  ·WriteEndTag方法

  寫入指定的標記元素的任何製表符間距和結束標記。

  ·Encoding屬性

  獲取 HtmlTextWriter 物件用於將內容寫入頁的編碼。

  ·Indent屬性

  獲取或設定用以縮排每一行標記的開始位置的製表符位置數。

  ·NewLine屬性

  獲取或設定由 HtmlTextWriter 物件使用的行結束符字串。

  對於初學者而言,建議重點掌握以上成員物件的應用。另外,ASP.NET 2.0還為HtmlTextWriter類新增了一些成員,這些成員包括:

  ·BeginRender方法

  通知 HtmlTextWriter 物件或派生類的物件,某個控制元件將會呈現。

  ·EndRender方法

  通知 HtmlTextWriter 物件或某個派生類的物件,某控制元件已完成呈現。

  ·IsValidFormAttribute方法

  檢查一個屬性以確保它可以在 <form> 標記元素的開始標記中呈現。

  ·WriteEncodedUrl方法

  對指定的 URL 進行編碼,然後將它寫入到輸出流。URL 可以包括引數。

  ·WriteEncodedText方法

  對請求的裝置的指定文字進行編碼,然後將其寫入到輸出流。

  ·WriteBreak方法

  將 <br /> 標記元素寫入到輸出流。

  使用Render方法實現控制元件呈現

  1、基礎知識

  本文所講解的Render方法隸屬於System.Web.UI.Controls.Control類。該類是建立伺服器控制元件的基類,很多控制元件類均繼承自該類。在Control類中包括三個用於實現控制元件呈現的方法:Render、RenderChildren和RenderControl。它們都使用HtmlTextWriter的例項作為引數,它們允許為一個HtmlTextWriter物件提供伺服器控制元件的內容,並將其內容封裝至HTTP輸出流中輸出到客戶端顯示。下面簡單對這三個方法進行簡單介紹。

  (1) protected virtual void Render(HtmlTextWriter writer);

  該方法用於將伺服器控制元件內容傳送到提供的HtmlTextWriter物件,此物件編寫將在客戶端呈現的內容。在開發伺服器控制元件時,可以重寫此方法以呈現伺服器控制元件。

  (2) protected virtual void RenderChildren(HtmlTextWriter writer);

  該方法用於將伺服器控制元件子級的內容輸出到提供的HtmlTextWriter物件,此物件編寫將在客戶端呈現的內容。該方法通知ASP.NET呈現頁中的所有Active Server Pages程式碼。如果頁上沒有任何ASP程式碼,此方法將呈現伺服器控制元件的所有子控制元件。

  (3) protected virtual void RenderControl(HtmlTextWriter writer);和protected void RenderControl (HtmlTextWriter writer,ControlAdapter adapter)

  RenderControl有兩個過載方法,它們都用於將伺服器控制元件的內容輸出到所提供的HtmlTextWriter物件中。如果已啟用跟蹤功能,則儲存有關控制元件的跟蹤資訊。如果伺服器控制元件的Visible屬性設定為true,該方法將確定是否啟用頁的跟蹤功能。如果啟用,它將儲存與控制元件有關的跟蹤資訊,同時向頁呈現伺服器控制元件的內容。另外,前一個過載方式是ASP.NET 2.0從ASP.NET 1.0中繼承而言,後一個過載方式是ASP.NET 2.0新增的。後者具體使用提供的ControlAdapter物件將伺服器控制元件內容輸出到提供的HtmlTextWriter物件。其中引數adapter是ControlAdapter型別,它用於定義呈現的ControlAdapter。當實現在各種裝置和瀏覽器中執行的伺服器控制元件時,該方法比較常用。

  以上3個方法看起來好像是獨立的3個方法,然而,實際上它們之間存在密切的聯絡。讀者可通過閱讀以下示意性程式碼,從而理解它們之間的關係。

//RenderCotrol方法基本實現
public void RenderControl(HtmlTextWriter output)
{
 if(Visible)
 {
  Render(output);
 }
}
//Render方法基本實現
protected virtual void Render(HtmlTextWriter output)
{
 RenderChildren(output);
}
//RenderChildren方法基本實現
protected virtual void RenderChildren(HtmlTextWriter output)
{
 foreach(Control c in Controls)
 {
  c.RenderControl(output);
 }
}
  如上程式碼所示,其中列舉了RenderControl、Render、RenderChildren方法的實現思路。顯而易見的是,在控制元件呈現過程中,這三個方法都在起著作用,而且使用了一個簡單的遞迴呼叫過程。大體而言,可以理解為:

  (1)頁面框架建立一個HtmlTextWriter類的例項;

  (2)頁面框架將這個例項物件傳遞給RenderControl方法;

  (3)RenderControl方法檢查控制元件的可視屬性Visible是否為true。如果為true,RenderControl方法將呼叫Render方法;如果為false,則不呈現該控制元件和其子控制元件;

  (4)Render方法執行預設實現,呼叫RenderChildren方法;

  (5)RenderChildren方法按照預設實現中的設定呼叫每個子控制元件的RenderControl方法;

  實際上,如果讀者短時間內不能理解以上過程也沒有很大的關係。對於初學者而言,關鍵是要記住最重要、最常用的是Render方法。控制元件開發者可以通過重寫Render方法完成呈現控制元件的任務。

  2、示例應用

  上文介紹了使用Control類的Render方法實現控制元件呈現的基礎知識。下面將通過一個典型示例,幫助讀者初步理解Render的使用方法。示例效果如圖1所示。

按此在新視窗瀏覽圖片
圖1效果圖
  如圖1所示,該伺服器控制元件呈現了一個超連結,並且設定了文字為紅色。當使用者單擊紅色文字時,頁面將轉向微軟站點。當然,使用者可以通過屬性LinkUrl來設定超連結地址。

  下面列舉了示例實現原始碼。

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Text;
using System.Web;
using System.Web.UI;
using System.Web.UI.WebControls;
namespace UsingRenderControl
{
 [DefaultProperty(“LinkUrl”)]
 [ToolboxData(“<{0}:RenderControl runat=server></{0}:RenderControl>”)]
 public class RenderControl : Control
 {
  // 實現LinkUrl
  [Bindable(true)]
  [Category(“Appearance”)]
  [DefaultValue(“http://localhost/”)]
  [Localizable(true)]
  public string LinkUrl
  {
   get { String s = (String)ViewState[“LinkUrl”];
    return ((s == null) ? String.Empty : s);}
   set { ViewState[“LinkUrl”] = value; }
  }
  // 重寫Render方法
  protected override void Render(HtmlTextWriter writer)
  {
   writer.AddAttribute(HtmlTextWriterAttribute.Href, LinkUrl);
   writer.AddStyleAttribute(HtmlTextWriterStyle.Color, “red”);
   writer.RenderBeginTag(HtmlTextWriterTag.A);
   writer.Write(“瀏覽網站”);
   writer.RenderEndTag();
  }
 }
}
  如上程式碼實現了自定義伺服器控制元件類RenderControl。該類從Control基類繼承,具體實現了表示超連結地址的LinkUrl(預設值為http://localhost/),並重寫了Render方法。在重寫Render的過程中,呼叫了一些HtmlTextWriter類成員,例如,Writer、AddAttribute、AddStyleAttribute、RenderBeginTag和RenderEndTag方法等。另外,可能開發人員在使用Writer方法過程中,需要呈現一個比較長的字串。建議此時多多使用Writer方法,而不要使用字串級聯或者StringBuilder類的相關方法進行實現。因為,那樣將會消耗大量的系統時間和記憶體,效率較低。

  可能有一些讀者會問,如果將伺服器控制元件呈現的多行程式碼的順序變化一下,是否會有什麼不同呢?例如,假設首先依次應用RenderBeginTag、Write、RenderEndTag方法,然後再呼叫AddAttribute和AddStyleAttribute方法,那麼會顯示相同的效果嗎?答案是否定的。這裡需要強調的是:在呈現控制元件的過程中,首先要定義伺服器控制元件的屬性和CSS樣式等內容,然後再定義伺服器控制元件的主體內容,這種順序不能改變的。

  另外,如果讀者感興趣可以在程式碼中實現一個Text屬性,用於獲取或者設定控制元件所顯示的文字。這樣,在Render方法中,使用Write方法輸出的”瀏覽網站”文字內容則可由Text屬性代替。

  下面列舉了為使用以上的自定義伺服器控制元件,而建立的Default.aspx檔案原始碼。

<%@ Page Language=”C#” AutoEventWireup=”true” CodeFile=”Default.aspx.cs” Inherits=”_Default” %>
<%@ Register TagPrefix=”Sample” Assembly=”UsingRenderControl” Namespace=”UsingRenderControl” %>
<!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>使用Render方法實現控制元件呈現</title>
</head>
<body>
<form id=”form1″ runat=”server”>
<div>
<Sample:RenderControl runat=”server” ID=”CustomerControl” LinkUrl=”http://www.microsoft.com/”>
</Sample:RenderControl>
</div>
</form>
</body>
</html>
  以上程式碼比較簡單,其中主要宣告瞭自定義伺服器控制元件RenderControl,並設定其LinkUrl屬性值為http://www.microsoft.com,即微軟站點地址。

  當使用者在瀏覽器中執行以上頁面,並檢視相關的Html原始檔時,可得到如下的程式碼:

<!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>
<title> 使用Render方法實現控制元件呈現</title>
</head>
<body>
<form name=”form1″ method=”post” action=”Default.aspx” id=”form1″>
<div>
<input type=”hidden” name=”__VIEWSTATE” id=”__VIEWSTATE” value=”/wEPDwUJNzMyMTY5NTU2ZGQQYrLd/G vm1h41r2CEkxID63o5g==” />
</div>
<div>
<a href=”http://www.microsoft.com/” style=”color:red;”>瀏覽網站</a>
</div>
</form>
</body>
</html>
  通過觀察以上程式碼可知,自定義伺服器控制元件RenderControl實際呈現的結果是粗體所示部分的程式碼,其最終呈現為一個表示超連結的<a>標記。

  小結

  本文首先介紹了HtmlTextWriter類的基本知識,然後講解了使用Render方法實現控制元件呈現的應用。在隨後的一篇文章中,筆者將說明另外一種實現控制元件呈現的方法。從伺服器控制元件開發技術總體而言,控制元件呈現技術是開發過程中最為常用,也是最為簡單的內容。建議讀者能夠熟練掌握其中的內容。

您可能感興趣的文章:

ASP.NET自定義Web伺服器控制元件之Button控制元件ASP.NET入門之HTML伺服器控制元件概述asp.net Textbox伺服器控制元件jQuery生成asp.net伺服器控制元件的程式碼ASP.NET 動態寫入伺服器端控制元件ASP.NET2.0伺服器控制元件之自定義狀態管理ASP.NET 2.0伺服器控制元件開發之複雜屬性ASP.NET2.0伺服器控制元件之型別轉換器ASP.NET伺服器控制元件的生命週期分析