资源描述
第11章用户控件和自定义控件.docx
《第11章用户控件和自定义控件.docx》由会员分享,可在线阅读,更多相关《第11章用户控件和自定义控件.docx(45页珍藏版)》请在冰豆网上搜索。
第11章用户控件和自定义控件
第11章用户控件和自定义控件
VS2008
在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为后缀名的,在VisualStudio2008中,可以通过【添加新项】选项创建一个用户控件,如图11-1所示。
图11-1创建用户控件
用户控件创建完毕后,会生成一个.ascx页面。
.ascx页面结构同.aspx页面基本没有什么区别。
在解决方案管理器中可以打开.aspx页面和.ascx页面进行对比,其结构并没有太大的变化,如图11-2和图11-3所示。
图11-2创建一个用户控件图11-3用户控件的结构
用户控件中并没有“
”等标记,因为.ascx页面作为控件被引用到其他页面,引用的页面(如.aspx页面)其中已经包含等标记。
而如果控件中使用这样的标记,可能会造成页面布局混乱。
用户控件创建完成后,.ascx页面代码如下所示。
<%@ControlLanguage="C#"AutoEventWireup="true"
CodeBehind="mycontrol.ascx.cs"Inherits="_11_1.mycontrol"%>
其中没有任何的“
”等标记,而.ascx.cs页面代码基本同.aspx相同,示例代码如下所示。
usingSystem;//使用系统命名空间
usingSystem.Collections;
usingSystem.Configuration;
usingSystem.Data;
usingSystem.Linq;
usingSystem.Web;//使用Web命名空间
usingSystem.Web.Security;
usingSystem.Web.UI;//使用UI命名控件
usingSystem.Web.UI.HtmlControls;//使用Html控件命名空间
usingSystem.Web.UI.WebControls;//使用Web控件命名空间
usingSystem.Web.UI.WebControls.WebParts;
usingSystem.Xml.Linq;//使用LINQ命名空间
namespace_11_1
{
publicpartialclassmycontrol:
System.Web.UI.UserControl//从控件类派生
{
protectedvoidPage_Load(objectsender,EventArgse)//页面加载方法
{
}
}
}
用户控件能够提高复用性,前面介绍的服务器控件,从很多情况下来说都可以看作是用户控件的一种。
当网站需要登录框时,不可能在每个需要登录的地方都重新编写一个登录框,最好的方法是每个页面都能够引用一个登录框。
当需要对登录框进行修改时,可以一次性的将所有的页面都修改完毕,而不需要对每个页面都修改登录框。
要达到这种目的,使用用户控件是最好不错的了。
.ascx页面允许开发人员拖动服务器控件,并编写相应的样式来实现用户控件,同时用户控件也能够支持事件、方法、委托等高级编程。
编写一个用户登录窗口,可以通过几个TextBox控件和Button控件来实现,示例代码如下所示。
<%@ControlLanguage="C#"
AutoEventWireup="true"CodeBehind="mycontrol.ascx.cs"Inherits="_11_1.mycontrol"%>
1pxsolid#ccc;width:
300px;background:
#f0f0f0;padding:
5px5px5px5px;font-size:
12px;">
用户登录
用户名:
TextBoxID="TextBox1"runat="server">
TextBox>
密码:
TextBoxID="TextBox2"runat="server">
TextBox>
ButtonID="Button1"runat="server"Text="登录"/>
HyperLinkID="HyperLink1"runat="server">还没有注册?
HyperLink>
上述代码创建了一个登录框界面。
当用户进行网站访问时,网站希望用户能够注册和登录到网站从而提高网站的用户粘度、提升访问量。
所以设置登录窗口是非常必要的,界面布局如图11-4所示。
图11-4编写用户登录界面
当界面布局完毕后,就需要为用户控件编写事件。
当用户单击【登录】按钮时,就需要进行事件操作。
同Web窗体一样,双击按钮同样会自动生成事件,示例代码如下所示。
protectedvoidButton1_Click(objectsender,EventArgse)
{
Label1.Text="登录成功";//显示登录信息
}
当单击【登录】按钮时,系统提示登录成功,当然这里只是一个简单的用户控件。
如果要实现复杂的用户控件的登录窗口,还需要对用户登录进行验证、查询和判断等功能。
当用户控件制作完毕后,就可以在其他页面引用用户控件,示例代码如下所示。
<%@RegisterTagPrefix="Sample"TagName="Login"Src="~/mycontrol.ascx"%>//声明控件引用
在这段代码中,有几个属性是必须编写的,这些属性的功能如下所示:
❑TagPrefix:
定义控件位置的命名控件。
有了命名空间的制约,就可以在同一个页面中使用不同功能的同名控件。
❑TagName:
指向所用的控件的名字。
❑Src:
用户控件的文件路径,可以为相对路径或绝对路径,但不能使用物理路径。
了解了相关属性,就能够在其他页面中引用该控件了,示例代码如下所示。
<%@PageLanguage="C#"
AutoEventWireup="true"CodeBehind="Default.aspx.cs"Inherits="_11_1._Default"%>
<%@RegisterTagPrefix="Sample"TagName="Login"Src="~/mycontrol.ascx"%>
//www.w3.org/1999/xhtml">
用户控件
Loginrunat="server"id="Login1">
Login>
上述代码声明了用户控件,并使用了用户控件,使用用户控件代码如下所示。
Loginrunat="server"id="Login1">
Login>//使用用户控件
从上述代码可以看出,用户控件的格式为TagPrefix:
TagName,当声明了用户控件后,就可以使用TagPrefix:
TagName的方式使用用户控件。
这样一个用户控件就使用完毕了,如图11-5所示。
图11-5使用用户控件
运行Default.aspx页面,虽然在Default.aspx页面中没有使用制作和编写任何控件,以及代码,但是却已经运行了登录框,这说明用户控件已经被运行了,如图11-6所示。
图11-6运行用户控件
当需要对登录框进行修改,而无需对页面进行修改时,只需要修改相应的用户控件即可。
当多个页面进行同样的用户控件的使用时,若需要对多个页面的控件进行样式或逻辑的更改只需要修改相应的控件,而不需要进行繁冗的多个页面的修正。
11.1.3将Web窗体转换成用户控件
在编写用户控件时,会发现Web窗体的结构和用户控件的结构基本相同。
如果开发人员已经开发了Web窗体,并在今后的需求中决定能够在应用程序全局中能够访问此Web窗体,那么就可以将Web窗体改成用户控件。
如果需要将Web窗体更改为用户控件,首先需要对比Web窗体和用户控件的区别:
❑Web窗体中有
等标记,而用户控件没有。
❑Web窗体和用户控件所声明的方法不同。
在了解以上区别后,就可以很容易的将Web窗体转换成用户控件。
首先,只需要删除
等标记即可。
在删除标记后,好需要对两种窗体的声明方式进行更改,对于Web窗体,其标记方式如下代码所示。
<%@PageLanguage="C#"
AutoEventWireup="true"CodeBehind="Default.aspx.cs"Inherits="_11_1._Default"%>
而对于用户控件,声明代码如下所示。
<%@ControlLanguage="C#"
AutoEventWireup="true"CodeBehind="mycontrol.ascx.cs"Inherits="_11_1.mycontrol"%>
在将Web窗体更改为用户控件时,只需要将PageLanguage更改为ControlLanguage即可。
这样就完成了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所示。
图11-7创建自定义控件
自定义控件创建完成后,会自动生成一个类,并在类中生成相应的方法,示例代码如下所示。
usingSystem;
usingSystem.Collections.Generic;
usingSystem.ComponentModel;
usingSystem.Linq;
usingSystem.Text;
usingSystem.Web;
usingSystem.Web.UI;
usingSystem.Web.UI.WebControls;//使用UI命名空间以便继承
namespaceServerControl1
{
[DefaultProperty("Text")]//声明属性
[ToolboxData("<{0}:
ServerControl1runat=server>{0}:
ServerControl1>")]//设置控件格式
publicclassServerControl1:
WebControl
{
[Bindable(true)]//设置是否支持绑定
[Category("Appearance")]//设置类别
[DefaultValue("")]//设置默认值
[Localizable(true)]//设置是否支持本地化操作
publicstringText//定义Text属性
{
get//获取属性
{
Strings=(String)ViewState["Text"];//获取属性的值
return((s==null)?
"["+this.ID+"]":
s);//返回默认的属性的值
}
set//设置属性
{
ViewState["Text"]=value;
}
}
protectedoverridevoidRenderContents(HtmlTextWriteroutput)//页面呈现
{
output.Write(Text);
}
}
}
开发人员可以在源代码中编写和添加属性。
当需要呈现给HTML页面输出时,只需要重写Render方法即可,示例代码如下所示。
protectedoverridevoidRenderContents(HtmlTextWriteroutput)
{
output.Write("定义的Text属性的值为:
"+Text);//输出为页面呈现
}
在使用服务器控件时,会发现控件有很多的属性,例如SqlConnection属性、Color属性等,如图11-8所示。
图11-8控件的属性
为了实现服务器控件的智能属性配置,开发人员能够在源代码中编写属性,示例代码如下所示。
publicstringGuoJingString//编写属性
{
get{return(String)ViewState["GuoJingString"];}//获取属性
set{ViewState["GuoJingString"]=value;}//设置属性
}
当自定义控件编写完毕后,需要在需要使用该控件的项目中添加引用。
右击现有项目,选择【添加引用】选项,如果是同在一个解决方案下,则只要选择【项目】选项卡即可。
而如果不在同一解决方案,则需要选择【浏览】选项卡浏览相应的DLL文件,如图11-9和图11-10所示。
图11-9添加项目引用图11-10浏览DLL
单击【确定】按钮完成引用的添加后,就可以在页面中使用此自定义控件。
若需要在页面中需要使用此自定义控件,同样同用户控件一样需要在头部声明自定义控件,示例代码如下所示。
<%@RegisterTagPrefix="MyControl"Namespace="ServerControl1"Assembly="ServerControl1"%>
上述代码向页面注册了自定义控件,自定义注册完毕后,就能够在页面中使用该控件。
同时,在工具栏中也会呈现自定义控件,如图11-11所示。
自定义控件呈现在工具箱之后,就可以直接拖动自定义控件到页面,并且配置相应的属性,如图11-12所示。
图11-11呈现自定义控件图11-12配置自定义属性
正如图11-12所示,开发人员能够在自定义控件中编写属性,这些属性可以是共有属性也可以是用户自定义的属性,用户可以拖动自定义控件使用于自己的应用程序中并通过属性进行自定义控件的配置。
用户拖动自定义页面到控件后,页面会生成相应的自定义控件的HTML代码,示例代码如下所示。
ServerControl1ID="ServerControl11"runat="server"/>
上述代码就在页面中使用了自定义控件。
在ASP.NET服务器控件中,很多的控件都是通过自定义控件来实现的,开发人员能够开发相应的自定义控件并在不同的应用中使用而无需重复开发。
11.2.2复合自定义控件
单单一个简单的控件并不能实现太多的效果,在实际开发中,可能需要更多的功能,这种复杂功能控件最常见的就是SqlDataSource控件。
SqlDataSource控件是数据源控件,通过SqlDataSource控件能够配置数据源,并且实现分页、插入、删除等功能。
复合自定义控件就类似这样一个功能复杂的控件。
编写复合自定义控件有以下几种方式:
❑创建用户控件,并使用用户控件封装的用户界面实现复合控件。
❑开发一个编译控件,封装一个按钮控件和文本框控件,通过重写Render方法呈现。
❑从现有的控件中派生出新控件。
❑从基本控件类之一派生来创建自定义控件。
通过编写复合控件,能够让控件开发更加灵活,控件的使用人员也能够更加方便的配置控件,例如,重写登录控件,前台页面制作人员使用该控件时,可以为控件配置验证等功能,方便前台人员配置和使用。
如图11-13所示。
图11-13登录控件
为了实现登录控件,就必须在自定义控件中添加相应的服务器控件,在登录控件中,需要两个TextBox来让用户输入用户名和密码,填写完成后,必须单击登录按钮实现登录事件。
在类中创建TextBox和Button代码如下所示。
publicclassServerControl1:
WebControl
{
//创建服务器控件
publicTextBoxNameTextBox=newTextBox();//创建TextBox控件
publicTextBoxPasswordTextBox=newTextBox();//创建密码控件
publicButtonLoginButton=newButton();//创建Button控件
…
…
}
上述代码创建了两个TextBox控件和一个Button控件。
其中,NameTextBox让用户能够输入用户名,而PasswordTextBox能够让用户输入密码。
当用户单击LoginButton时,就需要实现登录操作,在这里就需要声明一个事件,示例代码如下所示。
publiceventEventHandlerLoginClick;//声明事件
完成对控件和事件的声明,就需要进行属性的编写。
在登录控件中,希望在前台开发人员在开发过程中,能够轻易的配置属性进行使用,从而提高代码的复用性。
在图11-13所表示控件中,开发人员希望控件的使用人员能够配置背景颜色、边框粗细、内置距离、登录说明和跳转连接等。
在代码中,可以分别为这些属性进行配置,示例代码如下所示。
[Bindable(true)]//设置是否支持绑定
[Category("Appearance")]//设置类别
[DefaultValue("")]//设置默认值
[Localizable(true)]//设置是否支持本地化操作
publicstringLoignBackGroundColor//设置背景属性
{
get{return(String)ViewState["LoignBackGroundColor"];}//获取背景
set{ViewState["LoignBackGroundColor"]=value;}//设置背景
}
上述代码定义了一个属性,在属性定义前,可以对属性进行描述,如代码中Bindable、Category等,这些常用的描述意义如下所示:
❑Bindable:
是否用于绑定。
❑Category:
属性或事件显示在一个设置为“按分类顺序”的模式,如果不指定,则会显示在杂项中。
❑DefaultValue:
指定属性的默认值。
❑Localizable:
指定属性是否本地化。
编辑相应属性,在属性配置中就能够做相应的配置,如图11-14所示。
图11-14自定义属性
在代码中,将Category属性设置为Appearance,这个属性就会在【外观】选项卡中出现。
配置完成LoginBackGroundColor后,就可以为其他的属性做相应的配置,示例代码如下所示。
[Bindable(true)]//设置是否支持绑定
[Category("Appearance")]//设置类别
[DefaultValue("")]//设置默认值
[Localizable(true)]//设置是否支持本地化操作
publicstringLoignBackGroundColor//设置背景颜色
{
get{return(String)ViewState["LoignBackGroundColor"];}//获取属性的值
set{ViewState["LoignBackGroundColor"]=value;}//设置属性默认值
}
//登录边框粗细
[Bindable(true)]//设置是否支持绑定
[Category("Appearance")]//设置类别
[DefaultValue("")]//设置默认值
[Localizable(true)]//设置