ASP.NET服务器控件开发(2)--继承WebControl类
文章出處:http://www.cnblogs.com/gaoweipeng ?
前篇文章簡單介紹了如何封裝Html來創建我們的ASP.NET服務器控件。這篇說說如何繼承ASP.NET獨有的WebControl類來制作標準服務器控件。
先來介紹下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獲得焦點的時候背景色紅色,失去焦點時,背景是藍色。,當然,這里只是做個例子,獲得和失去焦點的樣式大家可以自己去設計。
這只是簡單的小應用,給大家提個思路。大家完全可以開動自己創新思維,創造出自己獨特的服務器控件。靈活的運用在我們得項目開發中。
轉載于:https://www.cnblogs.com/luoyaoquan/archive/2011/04/27/2030221.html
總結
以上是生活随笔為你收集整理的ASP.NET服务器控件开发(2)--继承WebControl类的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: Javascript 用本页面文本域中的
- 下一篇: 学习 jQuery下拉框,单选框,多选框