设为首页收藏本站language 语言切换
查看: 1463|回复: 0
收起左侧

ASP.NET 定制控件的开发(一)

[复制链接]
发表于 2010-2-25 10:23:35 | 显示全部楼层 |阅读模式
<p >在本篇文章的第一部分,我们讨论了如何创建用户控件。在第二部分,我们将讨论如何创建定制控件。有三种方法可以创建定制控件:<p >    .通过继承现有的控件创建派生定制控件。<p >    .通过将现有的控件组合为新控件,创建复合控件。<p >    .通过继承System.Web.UI.WebControls.WebControl创建完全定制的控件。<p >    复合控件与用户控件极为相似,其主要差别是复合控件被编译为了DLL文件,我们能够象使用任何服务器控件那样使用定制控件。<p ><ccid_nobr><strong>在Visual Studio .NET中创建定制控件</strong></ccid_nobr><p >    打开Visual Studio .NET,选择“新工程”,在“新工程”窗口中选择“Visual C#工程”或“Visual Basic工程”,创建一个被称作CustomControls的Web控制库,如下图所示:<p ><ccid_nobr><center><img  src="http://www.hh010.com/upload_files/article/244/9_rgkkjd15103.gif"></center></ccid_nobr><p >    读者会注意到,Visual Studio已经创建了一个名字为WebCustomControl1的完整的定制控件。在研究该控件时,我们将先创建一个Web应用对该控件进行测试。从“文件”菜单中选择“新工程”,在同一个目录下创建一个名字为CustomControlWebPage的工程。注意,一定要选择“添加方案”单选按钮,如下图所示:<p ><ccid_nobr><center><img  src="http://www.hh010.com/upload_files/article/244/9_d5pc8015104.gif"></center></ccid_nobr><p >    我们可以创建许多定制控件,并从该应用程序中对它们进行测试。右击CustomControls工程,调出快捷菜单,选择“属性”,如下图所示:<p ><ccid_nobr><center><img  src="http://www.hh010.com/upload_files/article/244/9_gpdyxn15105.gif"></center></ccid_nobr><p >    选择“配置属性”,将“输出路径”设置为与测试网页相同,如下图所示:<p ><ccid_nobr><center><img  src="http://www.hh010.com/upload_files/article/244/9_jkb6q315106.gif"></center></ccid_nobr><p >    通常情况下,当我们建立定制控件时,就会将.DLL文件拷贝到对它进行测试的网页的\bin目录。通过将输出设置为测试网页的\bin目录,我们就能够省掉这一步。<p ><ccid_nobr><strong>缺省的定制控件</strong></ccid_nobr><p >    Visual Studio .NET已经提供了一个名字为WebCustomControl1的定制控件,这是一个由继承System.Web.UI.WebControls.WebControl得到的完整定制控件。在完全理解它之前,我们可以在创建的测试网页中对它进行测试。打开WebForm1.aspx,并在其中添加一条注册新控件的命令:<p ><ccid_nobr><table width="550" border="1" cellspacing="0" cellpadding="0" bordercolorlight = "black" bordercolordark = "#FFFFFF" align="center"><tr><td bgcolor="e6e6e6" class="code">     &lt;%@Register TagPrefix="OReilly"<br>Namespace="CustomControls" <br>Assembly="CustomControls" %></td></tr></table></ccid_nobr><p >    上面的命令将向网页注册定制控件。我们再次使用了@Register标记,并提供了标记前缀(OReilly),而没有提供Tagname和src。但我们提供了能够唯一确定网页必须使用的控件、DLL的Namespace和Assembly。<p >    现在我们可以在网页上添加控件了,其中有二个属性我们必须设置:所有的服务器端组件都必需的Runat和决定在运行时控件如何显示的Text,其标记应当如下所示:<p ><ccid_nobr><table width="550" border="1" cellspacing="0" cellpadding="0" bordercolorlight = "black" bordercolordark = "#FFFFFF" align="center"><tr><td bgcolor="e6e6e6" class="code">     &lt;OReilly:WebCustomControl1 Runat="Server" Text="Hello World!" Id="WC1" /></td></tr></table></ccid_nobr><p >    当浏览测试网页时,传递的网页将显示出来,如下图所示:<p ><ccid_nobr><center><img  src="http://www.hh010.com/upload_files/article/244/9_i2gpzr15107.gif"></center></ccid_nobr><p >    下面分别是Visual Studio .NET中提供的C#版和VB.NET版的完整定制控件:<p ><ccid_nobr><strong>VS.NET中缺省的定制控件(C#)</strong></ccid_nobr><p ><ccid_nobr><table width="550" border="1" cellspacing="0" cellpadding="0" bordercolorlight = "black" bordercolordark = "#FFFFFF" align="center"><tr><td bgcolor="e6e6e6" class="code">     using  System;<br>  using  System.Web.UI;<br>  using  System.Web.UI.WebControls;<br>  using  System.ComponentModel;<br><br>  namespace  CustomControls<br>  {<br>        [DefaultProperty("Text"),<br>              ToolboxData("<{0}:WebCustomControl1 <br>                      runat=server></{0}:WebCustomControl1>")]<br>      public  class  WebCustomControl1  :  System.Web.UI.WebControls.WebControl<br>        {<br>              private  string  text;<br><br>              [Bindable(true),<br>                    Category("Appearance"),<br>                    DefaultValue("")]<br>              public  string  Text<br>              {<br>                    get<br>                    {<br>                          return  text;<br>                    }<br><br>                    set<br>                    {<br>                          text  =  value;<br>                    }<br>              }<br><br>              protected  override  void  Render(HtmlTextWriter  output)<br>              {<br>                    output.Write(Text);<br>              }<br>        }<br>  }    </td></tr></table></ccid_nobr><p ><ccid_nobr><strong>VS.NET中缺省的定制控件(VB.NET)</strong></ccid_nobr><p ><ccid_nobr><table width="550" border="1" cellspacing="0" cellpadding="0" bordercolorlight = "black" bordercolordark = "#FFFFFF" align="center"><tr><td bgcolor="e6e6e6" class="code">     Imports  System.ComponentModel<br>  Imports  System.Web.UI<br><br><DefaultProperty("Text"),  ToolboxData("<{0}:WebCustomControl1  runat=server></{0}:<br>  WebCustomControl1>")>  Public  Class  WebCustomControl1<br>        Inherits  System.Web.UI.WebControls.WebControl<br><br>        Dim  text  As  String<br><br><Bindable(True),  Category("Appearance"),  DefaultValue("")>  Property  [Text](    )  As  String<br>              Get<br>                    Return  text<br>              End  Get<br><br>              Set(ByVal  Value  As  String)<br>                    text  =  Value<br>              End  Set<br>        End  Property<br><br>        Protected  Overrides  Sub  Render(ByVal  output  As  System.Web.UI.HtmlTextWriter)<br>              output.Write([Text])<br>        End  Sub<br><br>  End  Class    </td></tr></table></ccid_nobr><p >    该控制中只包含一个由private性质的字符串型变量text支持的特性Text。<p ><ccid_nobr><I>表1:定制控件的通用属性</I></ccid_nobr><p ><ccid_nobr><table border="1" cellpadding="0" cellspacing="0"  bordercolor="#111111" width="550" ><tr><td>属性</td><td>描述</td></tr><tr><td>Bindable</td><td>布尔型,为true时表示VS.NET将在数据绑定对话框中显示该控件</td></tr><tr><td>Browsable</td><td>布尔型,表示该控件是否在设计视图中显示?</td></tr><tr><td>Category</td><td>当Properties按类别排序时,决定控件所属的种类。</td></tr><tr><td>DefaultValue</td><td>缺省值。</td></tr><tr><td>Description</td><td>在Properties面板中的描述框中显示的文本内容。</td></tr></table></ccid_nobr><p ><ccid_nobr><strong>特性</strong></ccid_nobr><p >    定制控件能够象其他类那样将特性提供给其他对象使用。我们能够通过编程或通过设置定制控件的属性值的方式访问这些特性:<p ><ccid_nobr><table width="550" border="1" cellspacing="0" cellpadding="0" bordercolorlight = "black" bordercolordark = "#FFFFFF" align="center"><tr><td bgcolor="e6e6e6" class="code"><OReilly:WebCustomControl1 Runat="Server" Text="Hello World!" /></td></tr></table></ccid_nobr><p >    控件的Text特性可以通过网页中的Text属性值进行访问。<p >    在上面的Text特性和Text属性值这种情况中,属性值和特性之间的映射是非常简单的,因为它们都是字符串类型。当然了,ASP.NET会提供其他类型之间的智能转换。例如,如果特性的数据类型为整型或长整型,属性值就要被转换为适当的类型。如果值是枚举型数据,ASP.NET将对字符串值和枚举变量名字进行匹配,然后设置正确的枚举变量值。如果是布尔型数据,ASP.NET将对字符串型数据与布尔型数据的值进行匹配,也就是说,字符串“True”与布尔型数据值true是匹配的。<p ><ccid_nobr><strong>Render方法</strong></ccid_nobr><p >    定制控件的主要方法是Render,这一方法是在基本类中定义的,如果要控制对网页的绘制,我们就必须在派生类中覆盖它。在上面的例子中,Render方法使用HtmlTextWriter作为参数显示Text特性中的字符串。<p >    HtmlTextWriter是由TextWriter派生生成的,提供了丰富的格式化功能。它能很好地组织生成的元素,并管理包括style在内的属性值。因此,如果想将文本设置为红色的,就可以添加一个红色属性值,如下所示:<p ><ccid_nobr><table width="550" border="1" cellspacing="0" cellpadding="0" bordercolorlight = "black" bordercolordark = "#FFFFFF" align="center"><tr><td bgcolor="e6e6e6" class="code">     output.AddStyleAttribute("color", ColorTranslator.ToHtml(Color.Red));    </td></tr></table></ccid_nobr><p >    我们还可以通过HtmlTextWriter的RenderBeginTag和RenderEndTag方法将文本设置在头部标记(<ccid_code>&lt;h2&gt;</ccid_code>)之间:<p ><ccid_nobr><table width="550" border="1" cellspacing="0" cellpadding="0" bordercolorlight = "black" bordercolordark = "#FFFFFF" align="center"><tr><td bgcolor="e6e6e6" class="code">     output.RenderBeginTag("h2");<br>output.Write(Text);<br>output.RenderEndTag(  );    </td></tr></table></ccid_nobr><p >    上面代码运行的结果就是当文本输出时生成的正确的标记,如下图所示:<p ><ccid_nobr><center><img  src="http://www.hh010.com/upload_files/article/244/9_if8qis15108.gif"></center></ccid_nobr><p ><ccid_nobr><strong>状态的维护</strong></ccid_nobr><p >    在下一个例子中,我们添加了一个使字体变大的按钮。为了实现这一功能,我们不能使用HtmlTextWriter的绘制功能,而应当通过使用新的Size特性(设置输出文本的大小)自己“写”这些文本。用C#编写的Render方法的代码如下:<p ><ccid_nobr><table width="550" border="1" cellspacing="0" cellpadding="0" bordercolorlight = "black" bordercolordark = "#FFFFFF" align="center"><tr><td bgcolor="e6e6e6" class="code">     protected override void Render(HtmlTextWriter output)<br>{<br>     output.Write("<font size = " + Size + ">" + Text + "</font>");<br>}    </td></tr></table></ccid_nobr><p >用VB.NET编写的Render方法代码如下:<p ><ccid_nobr><table width="550" border="1" cellspacing="0" cellpadding="0" bordercolorlight = "black" bordercolordark = "#FFFFFF" align="center"><tr><td bgcolor="e6e6e6" class="code">     Protected Overrides Sub Render(ByVal output As _<br>       System.Web.UI.HtmlTextWriter)<br>         output.Write("<font size = " & Size & ">" & [Text] & "</font>")End Sub    </td></tr></table></ccid_nobr><p >    在点击该按钮后,Size特性必须维持其状态。这非常简单,它与读、写由网页维护的ViewState集合一样简单,Size特性在C#语言中的定义为:<p ><ccid_nobr><table width="550" border="1" cellspacing="0" cellpadding="0" bordercolorlight = "black" bordercolordark = "#FFFFFF" align="center"><tr><td bgcolor="e6e6e6" class="code">     public int Size<br>{<br>   get { return Convert.ToInt32((string) ViewState["Size"]);  }<br>     set { ViewState["Size"] = value.ToString(  ); }<br>}<br></td></tr></table></ccid_nobr><p >    Size特性在VB.NET中的定义如下:<p ><ccid_nobr><table width="550" border="1" cellspacing="0" cellpadding="0" bordercolorlight = "black" bordercolordark = "#FFFFFF" align="center"><tr><td bgcolor="e6e6e6" class="code">     Public  Property  Size(    )  As  Integer<br>        Get<br>              Return  Convert.ToInt32(ViewState("Size"))<br>        End  Get<br>        Set(ByVal  Value  As  Integer)<br>              ViewState("Size")  =  Value.ToString(    )<br>        End  Set<br>  End  Property    </td></tr></table></ccid_nobr><p >    Get方法能够从ViewState中获取值,在C#中将获取的值指定为字符串型数据,然后将字符串转换为整型数据。Set方法将表示字体大小的字符串存入ViewState中。<p >    为了保证在开始时ViewState中的值是有效的,我们还应当在该控件中添加一个构造器。构造器的C#代码如下:<p ><ccid_nobr><table width="550" border="1" cellspacing="0" cellpadding="0" bordercolorlight = "black" bordercolordark = "#FFFFFF" align="center"><tr><td bgcolor="e6e6e6" class="code">     public  WebCustomControl1(    )<br>  {<br>        ViewState["Size"]  =  "1";<br>  }    </td></tr></table></ccid_nobr><p >构造器的VB.NET代码是:<p ><p ><ccid_nobr><table width="550" border="1" cellspacing="0" cellpadding="0" bordercolorlight = "black" bordercolordark = "#FFFFFF" align="center"><tr><td bgcolor="e6e6e6" class="code">     Public  Sub  New(    )<br>        ViewState("Size")  =  "1"<br>  End  Sub    </td></tr></table></ccid_nobr><p >    构造器将ViewState中的值初始化为1,每按一次该按钮,Size特性的值就会更新。为此,我们需要在网页中添加一个按钮定义:<p ><ccid_nobr><table width="550" border="1" cellspacing="0" cellpadding="0" bordercolorlight = "black" bordercolordark = "#FFFFFF" align="center"><tr><td bgcolor="e6e6e6" class="code"><asp:Button <br>      Runat="server" <br>      Text="Increase  Size" <br>      OnClick="Button1_Click" <br>        id="Button1"  /></td></tr></table></ccid_nobr><p >    这里最重要的变化是添加了ID属性值(Button1),并为该按钮定义了一个事件处理程序。我们还需要在代码中定义一个事件处理程序。<p >    一定要在网页上添加对CustomControls DLL文件的引用,这将使Intellisense知道我们的对象,而且能够在代码中定义控件。下面的C#代码将获得表单:<p ><ccid_nobr><table width="550" border="1" cellspacing="0" cellpadding="0" bordercolorlight = "black" bordercolordark = "#FFFFFF" align="center"><tr><td bgcolor="e6e6e6" class="code">     public class WebForm1 : System.Web.UI.Page<br> {<br>    protected System.Web.UI.WebControls.Button Button1;<br>       protected CustomControls.WebCustomControl1 WC1;    </td></tr></table></ccid_nobr><p >获得表单的VB.NET代码如下:<p ><p ><ccid_nobr><table width="550" border="1" cellspacing="0" cellpadding="0" bordercolorlight = "black" bordercolordark = "#FFFFFF" align="center"><tr><td bgcolor="e6e6e6" class="code">     Public  Class  WebForm1<br>        Inherits  System.Web.UI.Page<br><br>              Protected  WithEvents  Button1  As  System.Web.UI.WebControls.Button<br>              Protected  WC1  As  VBCustomControls.WebCustomControl1    </td></tr></table></ccid_nobr><p >    然后,我们就可以使用该定义设置在点击按钮的事件处理程序中的Size特性的值了,其C#代码如下:<p ><ccid_nobr><table width="550" border="1" cellspacing="0" cellpadding="0" bordercolorlight = "black" bordercolordark = "#FFFFFF" align="center"><tr><td bgcolor="e6e6e6" class="code">     public  void  Button1_Click(object  sender,  System.EventArgs  e)<br>  {<br>        WC1.Size  +=  1;<br>  }<br></td></tr></table></ccid_nobr><p >VB.NET代码与C#代码几乎完全相同:<p ><ccid_nobr><table width="550" border="1" cellspacing="0" cellpadding="0" bordercolorlight = "black" bordercolordark = "#FFFFFF" align="center"><tr><td bgcolor="e6e6e6" class="code"><br>ublic  Sub  Button1_Click(ByVal  sender  As  Object,  _<br>                                        ByVal  e  As  System.EventArgs)  Handles  Button1.Click<br>            WC1.Size  +=  1<br>  End  Sub    </td></tr></table></ccid_nobr><p align="center"><font color="FF0000" >1</font>2<span class="content01">下一页&gt;&gt;</span></p></p>
您需要登录后才可以回帖 登录 | 论坛注册

本版积分规则

QQ|Archiver|手机版|小黑屋|sitemap|鸿鹄论坛 ( 京ICP备14027439号 )  

GMT+8, 2025-4-5 00:53 , Processed in 0.079173 second(s), 24 queries , Redis On.  

  Powered by Discuz!

  © 2001-2025 HH010.COM

快速回复 返回顶部 返回列表