先來介紹下WebControl類
WebControl類:
WebControl 類從 Control 派生,用作定義 System.Web.UI.WebControls 命名空間中的所有控件的公共方法、屬性和事件的基類。提供所有 Web 服務器控件的公共屬性、方法和事件。通過設置在此類中定義的屬性,可以控制 Web 服務器控件的外觀和行爲。主要的屬性有:AccessKey、Attributes、 Width、Height等。此外,一個從 WebControl 派生的控件也自行參與到 ASP.NET 的主題功能。WebControl類的屬性和方法詳細的內容可以參看MSDN。
這裏再簡單的說下WebControl和HtmlContrlol的區別:
Web控件和Html控件雖然好多功能相同並且長得很像,但是它們的內部實現機制是完全不一樣的。
Web控件具有回送功能,能夠用ViewState維持控件的狀態。Html控件則不能,當點擊頁面的操作,其狀態就會丟失。(ViewState後面會有講解)
Html控件與Web控件最大的區別是它們對事件處理的方法不同。對於Html窗體控件,當引發一個事件時,瀏覽器會處理它。但對於Web控件,事件僅由瀏覽器生成,但瀏覽器不會處理它,客戶端要給服務器發個信息,告訴服務器處理事件。 不過有些事件,
比如:按下鍵/移動/鼠標等事件,Asp.net中沒有這些事件(因爲這些事件即時性強,服務器處理得不夠及時),這時候Html控件就發揮其作用了,結合Html事件協助完成。
有的資料上說:Web控件要比Html控件執行效率要好。這個沒有太好的依據,僅供大家參考,高手也可以談談自己的想法。
自己動手:
這裏我們不像上篇文章那樣,簡單的創建一個類庫工程,而是直接創建ASP.NET服務器控件項目。
VS2008會自動的爲我們生成如下代碼:
namespace SelfServerControl
{
[DefaultProperty("Text")]
[ToolboxData("<{0}:MyControl runat=server></{0}:MyControl>")]
public class MyControl : WebControl
{
[Bindable(true)]
[Category("Appearance")]
[DefaultValue("")]
[Localizable(true)]
public string Text
{
get
{
String s = (String)ViewState["Text"];
return ((s == null) ? "[" + this.ID + "]" : s);
}
set
{
ViewState["Text"] = value;
}
}
protected override void RenderContents(HtmlTextWriter output)
{
output.Write(Text);
}
}
}
代碼說明:
是不是有點熟悉,很像上節課繼承自Control類生成ASP.NET服務器控件的代碼。
代碼中定義了一個 Text 屬性(屬性的聲明和上篇基本一樣),並使用視圖狀態(ViewState )存儲該屬性值。使用視圖狀態保存回髮間的 Text 值。每次回發時,將重新創建頁並從視圖狀態還原值。如果 Text 值並未存儲在視圖狀態中,則在每次回發時會將值設置爲其默認的 Empty。ViewState 屬性繼承自 WebControl,是保存數據值的字典。通過使用 String 鍵,可輸入和檢索值。代碼中將“Text”用作鍵。字典中的項被類型化爲 Object,然後必須將其強制轉換爲屬性類型。
ViewState想必大家都已經很熟悉了,簡單的理解:當aspx頁面重新加載後,爲了避免上一次的存放在變量中的數據丟失,用ViewState來保存。
RenderContents 方法:
通常,在從 WebControl 派生控件並呈現單個元素時,應重寫 RenderContents 方法(而不是 Render 方法),以呈現控件標記中的內容。在呈現控件及其樣式屬性的開始標記之後,WebControl 的 Render 方法將調用 RenderContents。如果重寫 Render 方法以寫入內容,則控件將丟失生成到 WebControl 的 Render 方法中的樣式呈現邏輯。
如果我們將上篇的代碼複製到這裏,也能得到同樣的效果。這裏就不做演示了。
WebControl類爲開發人員提供了幾個特殊的方法,來完成我們對標註服務器控件的開發:
AddAttributesToRender(HtmlTextWriter.writer):WebControl的子類應該重寫該方法,以便包含用於呈現最外層HTML元素的HTML屬性的代碼塊
RenderBeginTag(HtmlTextWriter writer):WebControl的子類應該重寫該方法,以便包含用於呈現最外層HTML元素的打開標記的代碼塊
RenderContents(HtmlTextWriter writer): WebControl的子類應該重寫該方法,以便包含用於呈現最外層HTML元素的打開和關閉標記之間嵌套的HTML的代碼塊。
RenderEndTag(HtmlTextWriter writer):WebControl的子類應該重寫該方法,以便包含用於呈現最外層HTML元素的關閉標記的代碼塊
實現WebControl類的Render方法:
protected internal override void Render(HtmlTextWriter writer)
{
RenderBeginTag(writer);
RenderContents(writer);
RenderEndTag(writer);
}
AddAttributesToRender方法中發生了什麼。該方法將在RenderBeginTag方法中被調用。
具體的實例在這裏就不做了,給大家一個參看的例子。
簡單應用:
ASP.NET給我們提供了很多現成的控件,比如Label,button,textbox等等。在平時的開發中,我們完全可以不繼承Webcontrol類,直接繼承它下面控件的子類,這樣更有助於我們項目中的應用和開發。下面說個以前在項目中用到的小實例。
namespace MyTextBox
{
[DefaultProperty("Text"), ToolboxData("<{0}:BrianTextBox runat=server></{0}:BrianTextBox>"), Designer("System.Web.UI.Design.WebControls.PreviewControlDesigner, System.Design, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a")]
public class BrianTextBox : System.Web.UI.WebControls.TextBox
{
/// <summary>
/// 構造函數
/// </summary>
public BrianTextBox()
: base()
{
base.Attributes.Add("onfocus", "this.className='" + onFocus + "';");
base.Attributes.Add("onblur", "this.className='" + onBlurCss + "';");
base.CssClass = Class;
}
private string _onFocusCss = "colorfocus";
[Bindable(true), Category("Appearance"), Description("文本框獲取焦點時觸發")]
/// <summary>
/// 獲取焦點時樣式
/// </summary>
public string onFocus
{
get { return _onFocusCss; }
set { _onFocusCss = value; }
}
private string _onBlurCss = "colorblur";
[Bindable(true), Category("Appearance"), Description("文本框失去焦點時觸發")]
/// <summary>
/// 失去焦點時樣式
/// </summary>
public string onBlurCss
{
get { return _onBlurCss; }
set { _onBlurCss = value; }
}
private string _Class = "colorblur";
[Bindable(true), Category("Appearance"), DefaultValue("")]
/// <summary>
/// 樣式
/// </summary>
public string Class
{
get { return _Class; }
set { _Class = value; }
}
/// <summary>
/// 獲取焦點的控件ID(如提交按鈕等)
/// </summary>
[Bindable(true), Category("Appearance"), DefaultValue("")]
public string SetFocusButtonID
{
get
{
object o = ViewState[this.ClientID + "_SetFocusButtonID"];
return (o == null) ? "" : o.ToString();
}
set
{
ViewState[this.ClientID + "_SetFocusButtonID"] = value;
if (value != "")
{
this.Attributes.Add("onkeydown", "if(event.keyCode==13){document.getElementById('" + value + "').focus();}");
}
}
}
}
}
代碼不是很難,簡單說下。這裏我不是繼承自WebControl類,而是繼承自它的子類TextBox類,向父類中添加了兩個屬性,分別代表失去焦點時的樣式和獲取焦點時的樣式。還有一個屬性是獲取焦點的控件ID。這裏默認的設定了css的類名稱,所以在使用時,需要創建兩個css:
<style>
.colorblur
{
cursor:hand;
background-color:Aquamarine;
}
.colorfocus
{
cursor:hand;
background-color:Red;
}
</style>
不用做其他的任何設置,運行,會看到當我們得Textbox獲得焦點的時候背景色紅色,失去焦點時,背景是藍色。,當然,這裏只是做個例子,獲得和失去焦點的樣式大家可以自己去設計。
這只是簡單的小應用,給大家提個思路。大家完全可以開動自己創新思維,創造出自己獨特的服務器控件。靈活的運用在我們得項目開發中。
轉載地址:http://www.pin5i.com/showtopic-24404.html