【Asp.net精品源码栏目提醒】:网学会员为需要Asp.net精品源码的朋友们搜集整理了第11章.用户控件和自定义控件 - 其它资料相关资料,希望对各位网友有所帮助!
第 11 章 用户控件和自定义控件 在
ASP.NET 中,系统自带的服务器控件为应用程序开发提供了诸多便利。
在应用程序开发中,许多功能都需要重复使用,而如果在应用程序开发中重复的编写类似的代码是非常没有必要的。
ASP.NET让开发人员可以自行开发用户控件和自定义控件以提升代码的复用性,本章即将讲解用户控件和自定义控件的开发和使用。
11.1 用户控件 在 ASP 编程中,开发人员经常使用 Include 方式包含其他文件从而简化编程过程。
而在
ASP.NET中,控件能够提高应用程序中代码的复用性,不仅
ASP.NET 提供了服务器控件,
ASP.NET 还支持用户自定义控件,从而提高了代码的复用性。
11.1.1 什么是用户控件 用户控件使开发人员能够根据应用程序的需求,方便的定义和编写控件。
开发所使用的编程技术将与编写 Web 窗体的技术相同,只要开发人员对控件进行修改,就可以将使用该控件的页面的所有控件都进行更改。
为了确保用户控件不会被修改、下载,被当成一个独立的 Web 窗体来运行,用户控件的后缀名为.ascx,当用户访问页面时,用户控件是不能被用户直接访问的。
注意:虽然.ascx 文件会阻止用户的直接访问,但是一些常用的下载工具还是能够下载.ascx 文件。
11.1.2 编写一个简单的控件 用户控件是以.ascx 为后缀名的,在 Visual Studio 2008 中,可以通过【添加新项】选项创建一个用户控件,如图 11-1 所示。
图 11-1 创建用户控件 用户控件创建完毕后,会生成一个.ascx 页面。
.ascx 页面结构同.aspx 页面基本没有什么区别。
在解决方案管理器中可以打开.aspx 页面和.ascx 页面进行对比,其结构并没有太大的变化,如图 11-2 和图 11-3所示。
图 11-2 创建一个用户控件 图 11-3 用户控件的结构 用户控件中并没有“lthtmlgtltbodygt”等标记,因为.ascx 页面作为控件被引用到其他页面,引用的页面(如.aspx 页面)其中已经包含ltbodygtlthtmlgt等标记。
而如果控件中使用这样的标记,可能会造成页面布局混乱。
用户控件创建完成后,.ascx 页面代码如下所示。
lt Control LanguagequotCquot AutoEventWireupquottruequot CodeBehindquotmycontrol.ascx.csquot Inheritsquot_11_1.mycontrolquot gt 其中没有任何的“ltbodygtlthtmlgt”等标记,而.ascx.cs 页面代码基本同.aspx 相同,示例代码如下所示。
using System //使用系统命名空间 using System.Collections using System.Configuration using System.Data using System.Linq using System.Web //使用 Web 命名空间 using System.Web.Security using System.Web.UI //使用 UI 命名控件 using System.Web.UI.HtmlControls //使用 Html 控件命名空间 using System.Web.UI.WebControls //使用 Web 控件命名空间 using System.Web.UI.WebControls.WebParts using System.Xml.Linq //使用 LINQ 命名空间 namespace _11_1 public partial class mycontrol : System.Web.UI.UserControl //从控件类派生 protected void Page_Loadobject sender EventArgs e //页面加载方法 用户控件能够提高复用性,前面介绍的服务器控件,从很多情况下来说都可以看作是用户控件的一种。
当网站需要登录框时,不可能在每个需要登录的地方都重新编写一个登录框,最好的方法是每个页面都能够引用一个登录框。
当需要对登录框进行修改时,可以一次性的将所有的页面都修改完毕,而不 288需要对每个页面都修改登录框。
要达到这种目的,使用用户控件是最好不错的了。
.ascx 页面允许开发人员拖动服务器控件,并编写相应的样式来实现用户控件,同时用户控件也能够支持事件、方法、委托等高级编程。
编写一个用户登录窗口,可以通过几个 TextBox 控件和 Button 控件来实现,示例代码如下所示。
lt Control LanguagequotCquot AutoEventWireupquottruequot CodeBehindquotmycontrol.ascx.csquot Inheritsquot_11_1.mycontrolquot gt ltdiv stylequotborder:1px solid ccc width:300px background:f0f0f0 padding:5px 5px 5px 5px font-size:12pxquotgt 用户登录ltbr /gtltbr /gt 用户名 : ltasp:TextBox IDquotTextBox1quot runatquotserverquotgtlt/asp:TextBoxgtltbr /gtltbr /gt 密码: ltasp:TextBox IDquotTextBox2quot runatquotserverquotgtlt/asp:TextBoxgtltbr /gtltbr /gt ltasp:Button IDquotButton1quot runatquotserverquot Textquot登录quot /gt ltasp:HyperLink IDquotHyperLink1quot runatquotserverquotgt还没有注册lt/asp:HyperLinkgt lt/divgt 上述代码创建了一个登录框界面。
当用户进行网站访问时,网站希望用户能够注册和登录到网站从而提高网站的用户粘度、提升访问量。
所以设置登录窗口是非常必要的,界面布局如图 11-4 所示。
图 11-4 编写用户登录界面 当界面布局完毕后,就需要为用户控件编写事件。
当用户单击【登录】按钮时,就需要进行事件操作。
同 Web 窗体一样,双击按钮同样会自动生成事件,示例代码如下所示。
protected void Button1_Clickobject sender EventArgs e Label1.Text quot登录成功quot //显示登录信息 当单击【登录】按钮时,系统提示登录成功,当然这里只是一个简单的用户控件。
如果要实现复杂的用户控件的登录窗口,还需要对用户登录进行验证、查询和判断等功能。
当用户控件制作完毕后,就可以在其他页面引用用户控件,示例代码如下所示。
lt Register TagPrefixquotSamplequot TagNamequotLoginquot Srcquot/mycontrol.ascxquot gt //声明控件引用 在这段代码中,有几个属性是必须编写的,这些属性的功能如下所示: TagPrefix:定义控件位置的命名控件。
有了命名空间的制约,就可以在同一个页面中使用不同 功能的同名控件。
TagName:指向所用的控件的名字。
Src:用户控件的文件路径,可以为相对路径或绝对路径,但不能使用物理路径。
了解了相关属性,就能够在其他页面中引用该控件了,示例代码如下所示。
lt Page LanguagequotCquot AutoEventWireupquottruequot CodeBehindquotDefault.aspx.csquot Inheritsquot_11_1._Defaultquot gt lt Register TagPrefixquotSamplequot TagNamequotLoginquot Srcquot/mycontrol.ascxquot gt 289 lthtml xmlnsquothttp://www.w3.org/1999/xhtmlquot gt lthead runatquotserverquotgt lttitlegt用户控件lt/titlegt lt/headgt ltbodygt ltform idquotform1quot runatquotserverquotgt ltdivgt ltSample:Login runatquotserverquot idquotLogin1quotgtlt/Sample:Logingt lt/divgt lt/formgt lt/bodygt lt/htmlgt 上述代码声明了用户控件,并使用了用户控件,使用用户控件代码如下所示。
ltSample:Login runatquotserverquot idquotLogin1quotgtlt/Sample:Logingt //使用用户控件 从上述代码可以看出,用户控件的格式为 TagPrefix:TagName,当声明了用户控件后,就可以使用TagPrefix:TagName 的方式使用用户控件。
这样一个用户控件就使用完毕了,如图 11-5 所示。
图 11-5 使用用户控件 运行 Default.aspx 页面,虽然在 Default.aspx 页面中没有使用制作和编写任何控件,以及代码,但是却已经运行了登录框,这说明用户控件已经被运行了,如图 11-6 所示。
图 11-6 运行用户控件 当需要对登录框进行修改,而无需对页面进行修改时,只需要修改相应的用户控件即可。
当多个页 290面进行同样的用户控件的使用时,若需要对多个页面的控件进行样式或逻辑的更改只需要修改相应的控件,而不需要进行繁冗的多个页面的修正。
11.1.3 将 Web 窗体转换成用户控件 在编写用户控件时,会发现 Web 窗体的结构和用户控件的结构基本相同。
如果开发人员已经开发了 Web 窗体,并在今后的需求中决定能够在应用程序全局中能够访问此 Web 窗体,那么就可以将 Web窗体改成用户控件。
如果需要将 Web 窗体更改为用户控件, 首先需要对比 Web 窗体和用户控件的区别: Web 窗体中有ltbodygtlthtmlgtltheadgt等标记,而用户控件没有。
Web 窗体和用户控件所声明的方法不同。
在了 解 以 上 区 别 后 , 就 可 以 很 容 易 的 将 Web 窗体 转 换 成 用 户 控 件 。
首 先 , 只 需 要 删 除ltbodygtlthtmlgtltheadgt等标记即可。
在删除标记后,好需要对两种窗体的声明方式进行更改,对于 Web窗体,其标记方式如下代码所示。
lt Page LanguagequotCquot AutoEventWireupquottruequot CodeBehindquotDefault.aspx.csquot Inheritsquot_11_1._Defaultquot gt 而对于用户控件,声明代码如下所示。
lt Control LanguagequotCquot AutoEventWireupquottruequot CodeBehindquotmycontrol.ascx.csquot Inheritsquot_11_1.mycontrolquot gt 在将 Web 窗体更改为用户控件时,只需要将 Page Language 更改为 Control Language 即可。
这样就完成了 Web 窗体向用户控件的转换过程。
注意:有的时候,标记中还包括 ClassName 属性,当包含 ClassName 属性时,还需要修改相应的ClassName 属性。
11.2 自定义控件 用户控件能够执行很多操作。
并实现一些功能,但是在复杂的环境下,用户控件并不能够达到开发人员的要求,是因为用户控件大部分都是使用现有的控件进行组装,编写事件来达到目的。
于是,
ASP.NET 允许开发人员编写自定义控件实现复杂的功能。
11.2.1 实现自定义控件 自定义控件与用户控件不同,自定义控件需要定义一个直接或间接从 Control 类派生的类,并重写Render 方法。
在.NET 框架中,System.Web.UI.Control 与 System.Web.UI.WebControls.WebControl 两个类是服务器控件的基类,并且定义了所有服务器控件共有的属性、方法和事件,其中最为重要的就是包括了控制控件执行生命周期的方法和事件,以及 ID 等共有属性。
实现自定义控件,必须创建一个自定义控件,自定义控件将会编译成 DLL 文件。
创建自定义控件如图 11-7 所示。
291 图 11-7 创建自定义控件自定义控件创建完成后,会自动生成一个类,并在类中生成相应的方法,示例代码如下所示。
using Systemusing System.Collections.Genericusing System.ComponentModelusing System.Linqusing System.Textusing System.Webusing System.Web.UIusing System.Web.UI.WebControls //使用 UI 命名空间以便继承namespace ServerControl1 DefaultPropertyquotTextquot //声明属性 ToolboxDataquotlt0:ServerControl1 runatservergtlt/0:ServerControl1gtquot //设置控件格式 public class ServerControl1 : WebControl Bindabletrue //设置是否支持绑定 CategoryquotAppearancequot //设置类别 DefaultValuequotquot //设置默认值 Localizabletrue //设置是否支持本地化操作 public string Text //定义 Text 属性 get //获取属性 String s StringViewStatequotTextquot //获取属性的值 return s null quotquot this.ID quotquot : s //返回默认的属性的值 set //设置属性 ViewStatequotTextquot value protected override void RenderContentsHtmlTextWriter output //页面呈现 output.WriteText 292 开发人员可以在源代码中编写和添加属性。
当需要呈现给 HTML 页面输出时,只需要重写 Render方法即可,示例代码如下所示。
protected override void RenderContentsHtmlTextWriter output output.Writequot定义的 Text 属性的值为:quot Text //输出为页面呈现 在使用服务器控件时,会发现控件有很多的属性,例如 SqlConnection 属 性 、Color 属性等,如图 11-8所示。
图 11-8 控件的属性 为了实现服务器控件的智能属性配置,开发人员能够在源代码中编写属性,示例代码如下所示。
public string GuoJingString //编写属性 get return StringViewStatequotGuoJingStringquot //获取属性 set ViewStatequotGuoJingStringquot value //设置属性 当自定义控件编写完毕后,需要在需要使用该控件的项目中添加引用。
右击现有项目,选择【添加引用】选项,如果是同在一个解决方案下,则只要选择【项目】选项卡即可。
而如果不在同一解决方案 ,则需要选择【浏览】选项卡浏览相应的 DLL 文件,如图 11-9 和图 11-10 所示。
图 11-9 添加项目引用 图 11-10 浏览 DLL 293 单击【确定】按钮完成引用的添加后,就可以在页面中使用此自定义控件。
若需要在页面中需要使用此自定义控件,同样同用户控件一样需要在头部声明自定义控件,示例代码如下所示。
lt Register TagPrefixquotMyControlquot NamespacequotServerControl1quot AssemblyquotServerControl1quot gt 上述代码向页面注册了自定义控件,自定义注册完毕后,就能够在页面中使用该控件。
同时,在工具栏中也会呈现自定义控件,如图 11-11 所示。
自定义控件呈现在工具箱之后,就可以直接拖动自定义控件到页面,并且配置相应的属性,如图 11-12 所示。
图 11-11 呈现自定义控件 图 11-12 配置自定义属性 正如图 11-12 所示,开发人员能够在自定义控件中编写属性,这些属性可以是共有属性也可以是用户自定义的属性,用户可以拖动自定义控件使用于自己的应用程序中并通过属性进行自定义控件的配置。
用户拖动自定义页面到控件后,页面会生成相应的自定义控件的 HTML 代码,示例代码如下所示。
ltform idquotform1quot runatquotserverquotgt ltdivgt ltMyControl:ServerControl1 IDquotServerControl11quot runatquotserverquot /gt lt/divgt lt/formgt 上述代码就在页面中使用了自定义控件。
在
ASP.NET 服务器控件中,很多的控件都是通过自定义控件来实现的,开发人员能够开发相应的自定义控件并在不同的应用中使用而无需重复开发。
11.2.2 复合自定义控件 单单一个简单的控件并不能实现太多的效果,在实际开发中,可能需要更多的功能,这种复杂功能控件最常见的就是 SqlDataSource 控件。
SqlDataSource 控件是数据源控件,通过 SqlDataSource 控件能够配置数据源,并且实现分页、插入、删除等功能。
复合自定义控件就类似这样一个功能复杂的控件。
编写复合自定义控件有以下几种方式: 创建用户控件,并使用用户控件封装的用户界面实现复合控件。
开发一个编译控件,封装一个按钮控件和文本框控件,通过重写 Render 方法呈现。
从现有的控件中派生出新控件。
从基本控件类之一派生来创建自定义控件。
通过编写复合控件,能够让控件开发更加灵活, 控件的使用人员也能够更加方便的配置控件, 例如 ,重写登录控件,前台页面制作人员使用该控件时,可以为控件配置验证等功能,方便前台人员配置和使用。
如图 11-13 所示。
294 图 11-13 登录控件 为了实现登录控件,就必须在自定义控件中添加相应的服务器控件,在登录控件中,需要两个TextBox 来让用户输入用户名和密码,填写完成后,必须单击登录按钮实现登录事件。
在类中创建 TextBox和 Button 代码如下所示。
public class ServerControl1 : WebControl //创建服务器控件 public TextBox NameTextBox new TextBox //创建 TextBox 控件 public TextBox PasswordTextBox new TextBox //创建密码控件 public Button LoginButton new Button //创建 Button 控件 … … 上述代码创建了两个 TextBox 控件和一个 Button 控件。
其中,NameTextBox 让用户能够输入用户名,而 PasswordTextBox 能够让用户输入密码。
当用户单击 LoginButton 时,就需要实现登录操作,在这里就需要声明一个事件,示例代码如下所示。
public event EventHandler LoginClick //声明事件 完成对控件和事件的声明,就需要进行属性的编写。
在登录控件中,希望在前台开发人员在开发过程中,能够轻易的配置属性进行使用,从而提高代码的复用性。
在图 11-13 所表示控件中,开发人员希望控件的使用人员能够配置背景颜色、边框粗细、内置距离、登录说明和跳转连接等。
在代码中,可以分别为这些属性进行配置,示例代码如下所示。
Bindabletrue //设置是否支持绑定 CategoryquotAppearancequot //设置类别 DefaultValuequotquot //设置默认值 Localizabletrue //设置是否支持本地化操作 public string LoignBackGroundColor //设置背景属性 get return StringViewStatequotLoignBackGroundColorquot //获取背景 set ViewStatequotLoignBackGroundColorquot value //设置背景 上述代码定义了一个属性,在属性.