ASP.NET 定制控件的開發(fā)(一)
發(fā)表時間:2024-06-12 來源:明輝站整理相關(guān)軟件相關(guān)文章人氣:
[摘要]在本篇文章的第一部分,我們討論了如何創(chuàng)建用戶控件。在第二部分,我們將討論如何創(chuàng)建定制控件。有三種方法可以創(chuàng)建定制控件: .通過繼承現(xiàn)有的控件創(chuàng)建派生定制控件。 .通過將現(xiàn)有的控件組合為新控件,創(chuàng)建復(fù)合控件。 .通過繼承System.Web.UI.WebControls.WebControl創(chuàng)建完全...
在本篇文章的第一部分,我們討論了如何創(chuàng)建用戶控件。在第二部分,我們將討論如何創(chuàng)建定制控件。有三種方法可以創(chuàng)建定制控件:
.通過繼承現(xiàn)有的控件創(chuàng)建派生定制控件。
.通過將現(xiàn)有的控件組合為新控件,創(chuàng)建復(fù)合控件。
.通過繼承System.Web.UI.WebControls.WebControl創(chuàng)建完全定制的控件。
復(fù)合控件與用戶控件極為相似,其主要差別是復(fù)合控件被編譯為了DLL文件,我們能夠象使用任何服務(wù)器控件那樣使用定制控件。
在Visual Studio .NET中創(chuàng)建定制控件
打開Visual Studio .NET,選擇“新工程”,在“新工程”窗口中選擇“Visual C#工程”或“Visual Basic工程”,創(chuàng)建一個被稱作CustomControls的Web控制庫,如下圖所示:
讀者會注意到,Visual Studio已經(jīng)創(chuàng)建了一個名字為WebCustomControl1的完整的定制控件。在研究該控件時,我們將先創(chuàng)建一個Web應(yīng)用對該控件進(jìn)行測試。從“文件”菜單中選擇“新工程”,在同一個目錄下創(chuàng)建一個名字為CustomControlWebPage的工程。注意,一定要選擇“添加方案”單選按鈕,如下圖所示:
我們可以創(chuàng)建許多定制控件,并從該應(yīng)用程序中對它們進(jìn)行測試。右擊CustomControls工程,調(diào)出快捷菜單,選擇“屬性”,如下圖所示:
選擇“配置屬性”,將“輸出路徑”設(shè)置為與測試網(wǎng)頁相同,如下圖所示:
通常情況下,當(dāng)我們建立定制控件時,就會將.DLL文件拷貝到對它進(jìn)行測試的網(wǎng)頁的\bin目錄。通過將輸出設(shè)置為測試網(wǎng)頁的\bin目錄,我們就能夠省掉這一步。
缺省的定制控件
Visual Studio .NET已經(jīng)提供了一個名字為WebCustomControl1的定制控件,這是一個由繼承System.Web.UI.WebControls.WebControl得到的完整定制控件。在完全理解它之前,我們可以在創(chuàng)建的測試網(wǎng)頁中對它進(jìn)行測試。打開WebForm1.aspx,并在其中添加一條注冊新控件的命令:
<%@Register TagPrefix="OReilly"
Namespace="CustomControls"
Assembly="CustomControls" %>
上面的命令將向網(wǎng)頁注冊定制控件。我們再次使用了@Register標(biāo)記,并提供了標(biāo)記前綴(OReilly),而沒有提供Tagname和src。但我們提供了能夠唯一確定網(wǎng)頁必須使用的控件、DLL的Namespace和Assembly。
現(xiàn)在我們可以在網(wǎng)頁上添加控件了,其中有二個屬性我們必須設(shè)置:所有的服務(wù)器端組件都必需的Runat和決定在運(yùn)行時控件如何顯示的Text,其標(biāo)記應(yīng)當(dāng)如下所示:
<OReilly:WebCustomControl1 Runat="Server" Text="Hello World!" Id="WC1" />
當(dāng)瀏覽測試網(wǎng)頁時,傳遞的網(wǎng)頁將顯示出來,如下圖所示:
下面分別是Visual Studio .NET中提供的C#版和VB.NET版的完整定制控件:
VS.NET中缺省的定制控件(C#)
using System;
using System.Web.UI;
using System.Web.UI.WebControls;
using System.ComponentModel;
namespace CustomControls
{
[DefaultProperty("Text"),
ToolboxData("<{0}:WebCustomControl1
runat=server>")]
public class WebCustomControl1 : System.Web.UI.WebControls.WebControl
{
private string text;
[Bindable(true),
Category("Appearance"),
DefaultValue("")]
public string Text
{
get
{
return text;
}
set
{
text = value;
}
}
protected override void Render(HtmlTextWriter output)
{
output.Write(Text);
}
}
}
VS.NET中缺省的定制控件(VB.NET)
Imports System.ComponentModel
Imports System.Web.UI
WebCustomControl1>")> Public Class WebCustomControl1
Inherits System.Web.UI.WebControls.WebControl
Dim text As String
Property [Text]( ) As String
Get
Return text
End Get
Set(ByVal Value As String)
text = Value
End Set
End Property
Protected Overrides Sub Render(ByVal output As System.Web.UI.HtmlTextWriter)
output.Write([Text])
End Sub
End Class
該控制中只包含一個由private性質(zhì)的字符串型變量text支持的特性Text。
表1:定制控件的通用屬性
屬性描述Bindable布爾型,為true時表示VS.NET將在數(shù)據(jù)綁定對話框中顯示該控件Browsable布爾型,表示該控件是否在設(shè)計視圖中顯示?Category當(dāng)Properties按類別排序時,決定控件所屬的種類。DefaultValue缺省值。Description在Properties面板中的描述框中顯示的文本內(nèi)容。
特性
定制控件能夠象其他類那樣將特性提供給其他對象使用。我們能夠通過編程或通過設(shè)置定制控件的屬性值的方式訪問這些特性:
控件的Text特性可以通過網(wǎng)頁中的Text屬性值進(jìn)行訪問。
在上面的Text特性和Text屬性值這種情況中,屬性值和特性之間的映射是非常簡單的,因為它們都是字符串類型。當(dāng)然了,ASP.NET會提供其他類型之間的智能轉(zhuǎn)換。例如,如果特性的數(shù)據(jù)類型為整型或長整型,屬性值就要被轉(zhuǎn)換為適當(dāng)?shù)念愋。如果值是枚舉型數(shù)據(jù),ASP.NET將對字符串值和枚舉變量名字進(jìn)行匹配,然后設(shè)置正確的枚舉變量值。如果是布爾型數(shù)據(jù),ASP.NET將對字符串型數(shù)據(jù)與布爾型數(shù)據(jù)的值進(jìn)行匹配,也就是說,字符串“True”與布爾型數(shù)據(jù)值true是匹配的。
Render方法
定制控件的主要方法是Render,這一方法是在基本類中定義的,如果要控制對網(wǎng)頁的繪制,我們就必須在派生類中覆蓋它。在上面的例子中,Render方法使用HtmlTextWriter作為參數(shù)顯示Text特性中的字符串。
HtmlTextWriter是由TextWriter派生生成的,提供了豐富的格式化功能。它能很好地組織生成的元素,并管理包括style在內(nèi)的屬性值。因此,如果想將文本設(shè)置為紅色的,就可以添加一個紅色屬性值,如下所示:
output.AddStyleAttribute("color", ColorTranslator.ToHtml(Color.Red));
我們還可以通過HtmlTextWriter的RenderBeginTag和RenderEndTag方法將文本設(shè)置在頭部標(biāo)記(<h2>)之間:
output.RenderBeginTag("h2");
output.Write(Text);
output.RenderEndTag( );
上面代碼運(yùn)行的結(jié)果就是當(dāng)文本輸出時生成的正確的標(biāo)記,如下圖所示:
狀態(tài)的維護(hù)
在下一個例子中,我們添加了一個使字體變大的按鈕。為了實現(xiàn)這一功能,我們不能使用HtmlTextWriter的繪制功能,而應(yīng)當(dāng)通過使用新的Size特性(設(shè)置輸出文本的大。┳约骸皩憽边@些文本。用C#編寫的Render方法的代碼如下:
protected override void Render(HtmlTextWriter output)
{
output.Write("" + Text + "");
}
用VB.NET編寫的Render方法代碼如下:
Protected Overrides Sub Render(ByVal output As _
System.Web.UI.HtmlTextWriter)
output.Write("" & [Text] & "") End Sub
在點(diǎn)擊該按鈕后,Size特性必須維持其狀態(tài)。這非常簡單,它與讀、寫由網(wǎng)頁維護(hù)的ViewState集合一樣簡單,Size特性在C#語言中的定義為:
public int Size
{
get { return Convert.ToInt32((string) ViewState["Size"]); }
set { ViewState["Size"] = value.ToString( ); }
}
Size特性在VB.NET中的定義如下:
Public Property Size( ) As Integer
Get
Return Convert.ToInt32(ViewState("Size"))
End Get
Set(ByVal Value As Integer)
ViewState("Size") = Value.ToString( )
End Set
End Property
Get方法能夠從ViewState中獲取值,在C#中將獲取的值指定為字符串型數(shù)據(jù),然后將字符串轉(zhuǎn)換為整型數(shù)據(jù)。Set方法將表示字體大小的字符串存入ViewState中。
為了保證在開始時ViewState中的值是有效的,我們還應(yīng)當(dāng)在該控件中添加一個構(gòu)造器。構(gòu)造器的C#代碼如下:
public WebCustomControl1( )
{
ViewState["Size"] = "1";
}
構(gòu)造器的VB.NET代碼是:
Public Sub New( )
ViewState("Size") = "1"
End Sub
構(gòu)造器將ViewState中的值初始化為1,每按一次該按鈕,Size特性的值就會更新。為此,我們需要在網(wǎng)頁中添加一個按鈕定義:
這里最重要的變化是添加了ID屬性值(Button1),并為該按鈕定義了一個事件處理程序。我們還需要在代碼中定義一個事件處理程序。
一定要在網(wǎng)頁上添加對CustomControls DLL文件的引用,這將使Intellisense知道我們的對象,而且能夠在代碼中定義控件。下面的C#代碼將獲得表單:
public class WebForm1 : System.Web.UI.Page
{
protected System.Web.UI.WebControls.Button Button1;
protected CustomControls.WebCustomControl1 WC1;
獲得表單的VB.NET代碼如下:
Public Class WebForm1
Inherits System.Web.UI.Page
Protected WithEvents Button1 As System.Web.UI.WebControls.Button
Protected WC1 As VBCustomControls.WebCustomControl1
然后,我們就可以使用該定義設(shè)置在點(diǎn)擊按鈕的事件處理程序中的Size特性的值了,其C#代碼如下:
public void Button1_Click(object sender, System.EventArgs e)
{
WC1.Size += 1;
}
VB.NET代碼與C#代碼幾乎完全相同:
Public Sub Button1_Click(ByVal sender As Object, _
ByVal e As System.EventArgs) Handles Button1.Click
WC1.Size += 1
End Sub (出處:賽迪網(wǎng))