ASP.NET2.0服務器控件開發之控件樣式
隨著.NET技術的不斷發展和成熟,服務器控件越來越受到廣大開發人員的喜愛。同時,服務器控件的發展也呈現出一些趨勢,例如,功能越來越強大,很多功能逐漸從服務器端轉移到客戶端。另外,服務器控件也越來越美觀。這可能與Windows操作系統越來越講求功能與外觀統一的發展思路有關。本文及其隨后的幾篇文章將重點介紹如何為服務器控件實現漂亮的外觀。實際上,服務器控件的外觀主要由樣式屬性決定。本文重點對實現控件樣式的基本知識進行概括性講解。
服務器控件樣式簡介
對于普通應用開發人員而言,只需要知道服務器控件具有哪些樣式屬性,并了解每一個樣式屬性可能為控件外觀帶來的影響即可。例如,如果需要修改頁面背景顏色,則需要修改樣式屬性BackgroundColor值;如果需要設置表格對象外觀,那么可能需要設置BorderColor、BorderWidth等樣式屬性。然而,對于一名控件開發人員而言,他們不僅需要掌握應用開發人員所掌握的相關知識,而且還必須了解構建控件樣式屬性的創建方法。
通常,具有樣式屬性的服務器控件均繼承自System.Web.UI.WebControl基類。這樣,控件類可自動繼承基類中的多個樣式屬性。這些樣式屬性包括獲取或者設置控件背景顏色的BackColor、獲取或者設置控件前景顏色的ForeColor、獲取或者設置控件邊框顏色的BorderColor、獲取或者設置控件邊框樣式的BorderStyle等等。如果控件類從WebControl基類繼承,那么這些樣式屬性可自動得到繼承,并且允許開發人員根據具體情況,對這些樣式屬性進行重寫。另外,如果控件類繼承自其他現有控件類,例如 GridView,那么自定義控件將自動繼承GridView基類的樣式屬性,如設置交替數據行樣式的AlternatingRowStyle、設置正在編輯的數據行的樣式EditRowStyle等等。很顯然,這些繼承自已有服務器控件的樣式屬性并非此處要討論的重點。然而,讀者應了解樣式屬性允許從基類繼承并無需修改即可直接使用的。下面繼續討論WebControl類中的樣式屬性。
WebControl類的樣式均封裝在ControlStyle屬性中。該屬性值是Style數據類型。為了更好的了解ControlStyle,下面列舉了ControlStyle屬性的定義代碼。
如上代碼所示,ControlStyle是一個只讀屬性,其數據類型為Style。當第一次訪問該屬性的時候被創建,其過程為:首先,判斷_controlStyle是否為空,如果為空,則調用CreateControlStyle方法來創建_controlStyle對象,即一個Style的實例。然后,執行視圖狀態跟蹤任務,其具體過程由Style類所提供的TrackViewState方法來完成。
在初步了解ControlStyle屬性之后,接著我們應了解與該屬性密切相關的Style類。
Style類用于表示服務器控件的樣式,其包括以下幾個屬性:
(1)BackColor,獲取或者設置Web服務器控件的背景色;
(2)BorderColor,獲取或者設置控件的邊框顏色;
(3)BorderStyle,獲取或者設置控件的邊框樣式;
(4)BorderWidth,獲取或者設置控件的邊框寬度;
(5)CssClass,獲取或者設置控件在客戶端呈現的級聯樣式表類;
(6)Font,獲取與控件關聯的字體屬性;
(7)ForeColor,獲取或者設置控件的前景顏色;
(8)Height,獲取或者設置控件的高度;
(9)IsEmpty,獲取一個值,該值指示是否已經在ViewState中定義任何樣式元素;
(10)IsTrackingViewState,返回一個值,該值指示是否正在跟蹤其視圖狀態的更改。
(11)RegisteredCssClass,獲取已向控件注冊的級聯樣式表類;
(11)ViewState,獲取保存樣式元素的視圖狀態。
另外,Style類中還包括一些成員方法。利用它們可以很方便的對樣式進行操作。下面列舉了來自WebControl和Style類的,用于實現樣式操作的方法。
(1)protected virtural Style CreateControlStyle()
創建由WebControl類在內部用來實現所有與樣式有關的屬性的樣式對象。
(2)public void ApplyStyle(Style s)
將指定樣式的所有非空白元素復制到服務器控件,改寫控件的所有現有的樣式元素。其中s表示要復制的樣式。
(3)public void MergeStyle(Style s)
將指定樣式的所有非空白元素復制到服務器控件,但不改寫該控件現有的任何樣式元素。其中s表示要復制的樣式。
以上三個方法均來自WebControl類。下面兩個方法來自Style類。
(4)public virtual void CopyFrom(Style s)
將指定的Style的樣式屬性復制到從中調用此方法的Style類的實例中。s表示要復制的樣式的Style。使用此方法Style類的當前實例中的所有屬性都將替換為s參數指定的Style中的關聯屬性。
(5)public virtual void MergeWith(Style s)
將指定Style的樣式屬性與從中調用此方法的Style類的實例組合。其中s表示要合并的樣式的Style。此方法通過將每個在Style類的當前實例中未設置的屬性設置為s參數指定的Style的對應屬性中的值,將兩個Style對象的屬性聯接起來。只有尚未設置的屬性將被替換。如果沒有設置s參數中的屬性,則它將不替換Style類的當前實例中的對應屬性。
為了幫助讀者加深對于以上方法的理解,下面列舉了一段示例代碼。
上面的代碼比較簡單。Style對象實例s1在調用CopyFrom方法之后,其ForeColor的屬性值將被修改為Color.White;s1在調用MergeFrom之后,其ForeColor的屬性值則不變,仍然為Color.Red。
重寫樣式屬性
樣式屬性的重載與其他屬性的重載沒有什么區別。然而,在實現過程中必須注意的是,對屬性值所作的修改必須上傳給控件的ControlStyle屬性。下面列舉了一個示例應用程序,其重寫了Table控件的樣式屬性CellSpacing和Caption。服務器控件源代碼如下所示。
以上代碼主要用于說明重寫樣式屬性的實現方法。具體分析如下所示。
(1)控件類WebCustomControl繼承自Table。這樣,自定義控件則自動繼承了Table控件所具有的所有樣式屬性。這為重寫樣式屬性奠定了基礎。
(2)在控件類的構造函數中設置了Caption和CellSpacing的屬性值。
(3)重寫CellSpacing屬性。通過元數據屬性標記設置了該屬性不可被數據綁定(Bindable),告訴設計器該屬性不可被瀏覽(Browsable),最后設置了默認值為0(DefaultValue)。另外,在CellSpacing屬性的設置操作中定義了一個異常。當開發人員設置該屬性時將顯示該異常。
(4)重寫Caption屬性,為該屬性設置默認值。
可能有些讀者認為構造函數的設置內容沒有什么意義。實際上,實現本例的核心就在于此。只有在構造函數中設置新的屬性值,才能夠將新值傳遞給ControStyle屬性。因為ControlStyle屬性主要完成的工作是負責樣式狀態管理以及樣式屬性的生成。如果沒有把改變傳到ControlStyle,那么重寫的樣式屬性就不會按照預期的那樣顯示。
下面列舉了為測試自定義控件WebCustomControl而創建的Default.aspx頁面源代碼。
下面顯示了示例應用效果圖。
根據Default.aspx源代碼以及應用效果圖可知,上圖中的表格標題(Caption),以及相鄰表格間距(CellSpacing)均由自定義控件內置設置,而不是通過控件的顯式標記來完成。這就是重寫控件樣式屬性的結果。
小結
本文首先對服務器控件樣式的基本知識進行了簡要介紹,然后,通過一個典型示例說明了重寫控件樣式屬性的方法。希望讀者通過這些內容,能夠對服務器控件樣式屬性建立一個更為深入的理解。在隨后的文章中,我們將講解實現樣式屬性的具體方法。
服務器控件樣式簡介
對于普通應用開發人員而言,只需要知道服務器控件具有哪些樣式屬性,并了解每一個樣式屬性可能為控件外觀帶來的影響即可。例如,如果需要修改頁面背景顏色,則需要修改樣式屬性BackgroundColor值;如果需要設置表格對象外觀,那么可能需要設置BorderColor、BorderWidth等樣式屬性。然而,對于一名控件開發人員而言,他們不僅需要掌握應用開發人員所掌握的相關知識,而且還必須了解構建控件樣式屬性的創建方法。
通常,具有樣式屬性的服務器控件均繼承自System.Web.UI.WebControl基類。這樣,控件類可自動繼承基類中的多個樣式屬性。這些樣式屬性包括獲取或者設置控件背景顏色的BackColor、獲取或者設置控件前景顏色的ForeColor、獲取或者設置控件邊框顏色的BorderColor、獲取或者設置控件邊框樣式的BorderStyle等等。如果控件類從WebControl基類繼承,那么這些樣式屬性可自動得到繼承,并且允許開發人員根據具體情況,對這些樣式屬性進行重寫。另外,如果控件類繼承自其他現有控件類,例如 GridView,那么自定義控件將自動繼承GridView基類的樣式屬性,如設置交替數據行樣式的AlternatingRowStyle、設置正在編輯的數據行的樣式EditRowStyle等等。很顯然,這些繼承自已有服務器控件的樣式屬性并非此處要討論的重點。然而,讀者應了解樣式屬性允許從基類繼承并無需修改即可直接使用的。下面繼續討論WebControl類中的樣式屬性。
WebControl類的樣式均封裝在ControlStyle屬性中。該屬性值是Style數據類型。為了更好的了解ControlStyle,下面列舉了ControlStyle屬性的定義代碼。
| private Style _controlStyle; //定義ControlStyle屬性 public Style ControlStyle{ get { if(_controlStyle == null) { _controlStyle = CreateControlStyle(); if(IsTrackingViewState) { ((IStateManager)_controlStyle).TrackViewState(); } } } } //定義CreateControlStyle方法 protected virtual Style CreateControlStyle(){ return new Style(ViewState);} |
如上代碼所示,ControlStyle是一個只讀屬性,其數據類型為Style。當第一次訪問該屬性的時候被創建,其過程為:首先,判斷_controlStyle是否為空,如果為空,則調用CreateControlStyle方法來創建_controlStyle對象,即一個Style的實例。然后,執行視圖狀態跟蹤任務,其具體過程由Style類所提供的TrackViewState方法來完成。
在初步了解ControlStyle屬性之后,接著我們應了解與該屬性密切相關的Style類。
Style類用于表示服務器控件的樣式,其包括以下幾個屬性:
(1)BackColor,獲取或者設置Web服務器控件的背景色;
(2)BorderColor,獲取或者設置控件的邊框顏色;
(3)BorderStyle,獲取或者設置控件的邊框樣式;
(4)BorderWidth,獲取或者設置控件的邊框寬度;
(5)CssClass,獲取或者設置控件在客戶端呈現的級聯樣式表類;
(6)Font,獲取與控件關聯的字體屬性;
(7)ForeColor,獲取或者設置控件的前景顏色;
(8)Height,獲取或者設置控件的高度;
(9)IsEmpty,獲取一個值,該值指示是否已經在ViewState中定義任何樣式元素;
(10)IsTrackingViewState,返回一個值,該值指示是否正在跟蹤其視圖狀態的更改。
(11)RegisteredCssClass,獲取已向控件注冊的級聯樣式表類;
(11)ViewState,獲取保存樣式元素的視圖狀態。
另外,Style類中還包括一些成員方法。利用它們可以很方便的對樣式進行操作。下面列舉了來自WebControl和Style類的,用于實現樣式操作的方法。
(1)protected virtural Style CreateControlStyle()
創建由WebControl類在內部用來實現所有與樣式有關的屬性的樣式對象。
(2)public void ApplyStyle(Style s)
將指定樣式的所有非空白元素復制到服務器控件,改寫控件的所有現有的樣式元素。其中s表示要復制的樣式。
(3)public void MergeStyle(Style s)
將指定樣式的所有非空白元素復制到服務器控件,但不改寫該控件現有的任何樣式元素。其中s表示要復制的樣式。
以上三個方法均來自WebControl類。下面兩個方法來自Style類。
(4)public virtual void CopyFrom(Style s)
將指定的Style的樣式屬性復制到從中調用此方法的Style類的實例中。s表示要復制的樣式的Style。使用此方法Style類的當前實例中的所有屬性都將替換為s參數指定的Style中的關聯屬性。
(5)public virtual void MergeWith(Style s)
將指定Style的樣式屬性與從中調用此方法的Style類的實例組合。其中s表示要合并的樣式的Style。此方法通過將每個在Style類的當前實例中未設置的屬性設置為s參數指定的Style的對應屬性中的值,將兩個Style對象的屬性聯接起來。只有尚未設置的屬性將被替換。如果沒有設置s參數中的屬性,則它將不替換Style類的當前實例中的對應屬性。
為了幫助讀者加深對于以上方法的理解,下面列舉了一段示例代碼。
| //定義兩個Style對象實例 Style s1 = new Style(); Style s2 = new Style(); //分別為s1和s2定義ForeColor屬性值 s1.ForeColor = Color.Red; s2.ForeColor = Color.White; //調用相關方法 s1.CopyFrom(s2); s1.MergeFrom(s2); |
上面的代碼比較簡單。Style對象實例s1在調用CopyFrom方法之后,其ForeColor的屬性值將被修改為Color.White;s1在調用MergeFrom之后,其ForeColor的屬性值則不變,仍然為Color.Red。
重寫樣式屬性
樣式屬性的重載與其他屬性的重載沒有什么區別。然而,在實現過程中必須注意的是,對屬性值所作的修改必須上傳給控件的ControlStyle屬性。下面列舉了一個示例應用程序,其重寫了Table控件的樣式屬性CellSpacing和Caption。服務器控件源代碼如下所示。
| 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 WebControlLibrary{ [DefaultProperty("Text")] [ToolboxData("<{0}:WebCustomControl runat=server></{0}:WebCustomControl>")] public class WebCustomControl : Table { //創建構造函數 public WebCustomControl() { base.Caption = "工作安排列表"; base.CellSpacing = 0; } // 重寫CellSpacing屬性 [ Bindable(false), Browsable(false), DefaultValue(0) ] public override int CellSpacing { get { return base.CellSpacing; } set { throw new NotSupportedException("不能設置CellSpacing屬性."); } } //重寫Caption屬性 [DefaultValue("工作安排列表")] public override string Caption { get { return base.Caption; } set { base.Caption = value; } } } } |
以上代碼主要用于說明重寫樣式屬性的實現方法。具體分析如下所示。
(1)控件類WebCustomControl繼承自Table。這樣,自定義控件則自動繼承了Table控件所具有的所有樣式屬性。這為重寫樣式屬性奠定了基礎。
(2)在控件類的構造函數中設置了Caption和CellSpacing的屬性值。
(3)重寫CellSpacing屬性。通過元數據屬性標記設置了該屬性不可被數據綁定(Bindable),告訴設計器該屬性不可被瀏覽(Browsable),最后設置了默認值為0(DefaultValue)。另外,在CellSpacing屬性的設置操作中定義了一個異常。當開發人員設置該屬性時將顯示該異常。
(4)重寫Caption屬性,為該屬性設置默認值。
可能有些讀者認為構造函數的設置內容沒有什么意義。實際上,實現本例的核心就在于此。只有在構造函數中設置新的屬性值,才能夠將新值傳遞給ControStyle屬性。因為ControlStyle屬性主要完成的工作是負責樣式狀態管理以及樣式屬性的生成。如果沒有把改變傳到ControlStyle,那么重寫的樣式屬性就不會按照預期的那樣顯示。
下面列舉了為測試自定義控件WebCustomControl而創建的Default.aspx頁面源代碼。
| <%@ Page Language="C#" AutoEventWireup="true" CodeFile="Default.aspx.cs" Inherits="_Default" %> <%@ Register TagPrefix="wcc" Namespace="WebControlLibrary" Assembly="WebControlLibrary" %> <!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> <wcc:WebCustomControl ID="demo1" runat="server" Font-Size="small" BorderWidth="1px" CellPadding="4" BorderColor="black" GridLines="both"> <asp:TableRow> <asp:TableCell font-bold="True" runat="server">工作項目</asp:TableCell> <asp:TableCell font-bold="True" runat="server">截至日期</asp:TableCell> <asp:TableCell font-bold="True" runat="server">備注</asp:TableCell> </asp:TableRow> <asp:TableRow runat="server"> <asp:TableCell runat="server">工作1</asp:TableCell> <asp:TableCell runat="server">7月17日</asp:TableCell> <asp:TableCell runat="server">備注內容</asp:TableCell> </asp:TableRow> <asp:TableRow runat="server"> <asp:TableCell runat="server">工作2</asp:TableCell> <asp:TableCell runat="server">7月27日</asp:TableCell> <asp:TableCell runat="server">備注內容</asp:TableCell> </asp:TableRow> <asp:TableRow runat="server"> <asp:TableCell runat="server">工作3</asp:TableCell> <asp:TableCell runat="server">7月29日</asp:TableCell> <asp:TableCell runat="server">備注內容</asp:TableCell> </asp:TableRow> </wcc:WebCustomControl> </div> </form> </body> </html> |
下面顯示了示例應用效果圖。
![]() |
根據Default.aspx源代碼以及應用效果圖可知,上圖中的表格標題(Caption),以及相鄰表格間距(CellSpacing)均由自定義控件內置設置,而不是通過控件的顯式標記來完成。這就是重寫控件樣式屬性的結果。
小結
本文首先對服務器控件樣式的基本知識進行了簡要介紹,然后,通過一個典型示例說明了重寫控件樣式屬性的方法。希望讀者通過這些內容,能夠對服務器控件樣式屬性建立一個更為深入的理解。在隨后的文章中,我們將講解實現樣式屬性的具體方法。
