用ASP.NET創建自定義文本框
|
在一個.NET的應用程序中使用自己創建的控件可以大大增強應用程序的功能,你可以在原有控件的基礎上加入想要的屬性和行為,甚至創建自定義的控件。在asp.net中,我們更可以往一些控件中增加一些客戶端的javascript功能,減少每次在提交頁面時將數據返回給服務器的次數 ,從而提高程序的功能和效率。在這篇文章中,我們將看下,如何用asp.net創建一個自定義的文本框控件,當焦點在該文本框控件上及離開控件時,文本框控件的背景顏色會隨之改變。這個控件將包含如下的功能:
1) 當用戶在文本框輸入數據時,文本框的背景顏色以預先設定的顏色顯示,當用戶的輸入焦點離開文本框時,能恢復原來文本框的背景顏色。
2)可以在vs.net的設計期間,改變該自定義控件的各項屬性。
下面我們開始一步步創建該控件。首先,創建一個空的vs.net解決方案,增加一個asp.net工程(命名為webapplication)和一個web控件庫工程(命名為ControLib)。將asp.net工程中的webform1.aspx重新命名為container.aspx;將web控件庫工程中的webcustomercontrol1.cs重新命名為PimpedOutTextbox.cs。命名后如下圖所示:

接著,往pimpedouttextbox類中添加代碼。因為這是個WEB控件庫,VS.NET已經引入相關的類庫。由于我們這個應用將會用到顏色方面的功能,所以引入繪圖類。
using System.Drawing; |
再用如下的代碼替換原來預定義的代碼。
line 1: [assembly: TagPrefix ( "ControlLib" , "lib" )] line 2: namespace ControlLib line 3: { line 4: [DefaultProperty( "BackColorOn" ), line 5: ToolboxData( "<{0}:PimpedOutTextbox runat=server></{0}:PimpedOutTextbox>" )] line 6: public class PimpedOutTextbox : System.Web.UI.WebControls.TextBox line 7: { |
在一開始,增加了assembly屬性,其目的是,當在vs.net中拖拉該控件時,VS.net會自動添加Tagprefix的控件標記。在pimedouttexbox類中,增加了幾個屬性:defaultproperty和toolboxdata.defaultproperty中的屬性backcoloron的含義是,當把該控件從VS.NET的工具箱拖拉到設計器時,該控件中被默認選定的屬性。Toolboxdata屬性是和[assembly:Tagprefix]屬性相關,用來表明該控件是如何從HTML視圖中產生的。這些屬性將在下文詳細講解。
最后,在第6行,注意 public class PimpedOutTextbox : System.Web.UI.WebControls.TextBox 一句,其中表明這個控件是比原來的文本框控件增加了新的行為。總的來說,我們創建的這個控件依然是一個文本框控件,只不過是繼承了原有文本框控件的屬性和行為,并且有自己的新的屬性而已。
下一步,將給pimedouttextbox控件新增兩個屬性。其中,我們設想,當用戶在文本框中輸入或者文本框獲得焦點時,文本框的顏色有變化,所以命名新的屬性BackColoron;當控件失去焦點時,文本框的顏色命名為backcoloroff。
line 1: private Color _colOff; line 2: [Category( "Appearance" ), Description( "The background color when the control loses focus" )] line 3: public Color BackColorOff line 4: { line 5: get{return _colOff;} line 6: set{_colOff = value line 7: } line 8: private Color _colOn; line 9: [Category( "Appearance" ), Description( "The background color when the control has the focus" )] line 10: public Color BackColorOn line 11: { line 12: get{return _colOn; } line 13: set{_colOn = value;} line 14: } |
上面的代碼,是典型的對屬性的賦值和存取的語句了,相信大家都很熟悉了。要提及一點的是,第2行和第9行的category和descriptiton屬性,是該控件的屬性窗口中,對backcoloron和backcoloroff兩個屬性的一個描述。注意,我們使用了color類,這樣比較方便,可以用vs.net自帶的顏色選擇器,而不用輸入顏色的十六進制值。
接著,下面是比較重要的部分。在這個新的控件, 我們將用重載一個AddAttributesToRender()的方法輸出新的內容到瀏覽器中。其中,將加入對客戶端的onfocus和onblur事件的響應。另外,要注意的是,當在VS.NET創建該控件時,會自動調用該方法,所以我們可以在設計期間對其中的屬性進行設置。
line 1: protected override void AddAttributesToRender( HtmlTextWriter writer ) line 2: { line 3: base.AddAttributesToRender( writer ); line 4: //only add the client-side javascript for design mode or IE line 5: if( inDesignMode() || System.Web.HttpContext.Current.Request.Browser.Type.IndexOf( "IE" ) > -1 ) line 6: { line 7: writer.AddAttribute( "onFocus", "JavaScript:this.style.backgroundColor='" + ColorTranslator.ToHtml( _colOn ) + "';" ); line 8: if( _colOff.Equals( Color.Empty ) ) line 9: { line 10: _colOff = this.BackColor; line 11: } line 12: writer.AddAttribute( "onBlur", "JavaScript:this.style.backgroundColor='" + ColorTranslator.ToHtml( colOff ) + "';" ); line 13: } line 14: } |
其中第3行的目的是,調用基類,繼承原有的文本框的屬性。AddAttributesToRender的方法使用HtmlTextWriter流作為參數。在第9,第12行,分別通過調用HTML文本流的AddAttribute方法增加其客戶端的輸出。其中傳入了兩個參數,第一個參數是HTML的屬性,第二個是屬性對應的值。它們經過瀏覽器輸出后,變為<input type="text" onBlur="JavaScript...">的形式。
因為瀏覽器使用的是十六進制的顏色,所以我們采用ColorTranslator類去將.NET的顏色類型轉換為瀏覽器中能識別的顏色類型(第7和第12行)。在第8行,先檢查_coloroff屬性是否沒被賦值,如果沒賦值,則backcoloroff的顏色設置為原來文本框的背景色。
而在第5行,我們檢查瀏覽器的類型是否支持onfocus和onblur事件,并且由于想在VS.NET的設計時就能對控件的屬性進行改變,所以增加了一個判斷的函數indesignmode:
line 1: private bool inDesignMode() line 2: { line 3: bool blnOut = false; line 4: if( object.ReferenceEquals( System.Web.HttpContext.Current, null ) ) line 5: { line 6: blnOut = true; line 7: } line 8: else line 9: { line 10: blnOut = false; line 11: } line 12: return blnOut; line 13: } |
在上面代碼的第4行,通過判斷如果HttpContext實例是否為null,如果為null的話,則證明當前是處于VS.NET的設計模式下,沒響應HTTP請求。接下來,我們測試一下所做的控件。
首先,我們編譯做好的控件工程,之后,我們在ASP.NET的工程中,加入剛做好的控件。方法是,鼠標右鍵點擊webapplication中的增加引用,其中選擇剛才編譯好的控件庫目錄中的dll文件即可。再在vs.net的工具箱中,同樣增加新的項,選擇剛做好的控件庫目錄中的dll,這時,你會發現在工具箱中多了剛才做的pimedouttextbox。如下圖:

接著,從工具箱中將我們做的控件拖拉到頁面中來。注意,這個時候該控件的屬性頁中,會自動定位在BackColoron屬性中。這是因為之前我們設置了DefaultProperty屬性。同時注意該屬性下的說明文字,這是因為設置了description屬性。再切換到HTML視圖中去,你會看到
<%@ Register TagPrefix="lib" Namespace="ControlLib" Assembly="ControlLib" %> |
這是由于之前對
[assembly: TagPrefix ( "ControlLib" , "lib" )] |
的定義而產生的。
再切換回設計視圖,將該文本框控件的顏色設置為灰色,會發現同時backcoloroff也同樣設置為同樣的顏色了,因為之前backcoloroff是沒有被賦值的。再改變文本框的背景色,這是會發現backcoloroff的值沒變化了,因為這個時候backcoloroff的值已經不是空值了(具體可以再看上文的代碼)。接下來,將文本框的背景顏色設置為除白色外的任一種顏色,運行程序。結果時,當該文本框控件獲得焦點時,文本框的顏色以backcoloron的顏色顯示,當文本框失去焦點時,文本框的顏色以backcoloroff顯示。
如果你想對客戶端的代碼進行單步跟蹤,可以將debugger;加入到要調試的javascript語句中去,如
JavaScript:debugger;this.style.backgroundColor='blue'; |
運行程序,則可以通過監視窗口監視相關的變量,如輸入document.forms[0].all[1].name等。
以上只是簡單介紹了asp.net中如何創建自定義的控件,相信讀者會有所啟發。程序可以在vs.net 2002,2003上調試運行。