- 第3章 Web标准服务器控件
第3章 Web标准服务器控件
在ASP.NET中,Web标准服务器控件是ASP.NET服务器控件的核心部件,也是Web Forms编程模型的基本元素。相对于HTML服务器控件而言,它具有更多内置功能和可编程性。它不仅包括简单的窗体控件(例如按钮和文本框等),而且还包括一些具有特殊用途的控件(例如日历、菜单和树视图控件等)。同时,它还提供了统一的编程接口,让你可以在它的基础之上自由扩展成自己所需要的控件。本章将重点讲解Web标准服务器控件的使用方法与编程技巧。
3.1 Web标准服务器控件概述
类似于HTML服务器控件,Web标准服务器控件同样在服务器端创建,且需要runat="server"属性才能工作。可以把它们看成是服务器上执行程序逻辑的组件,这个组件可能生成一定的用户界面,也可能不包括用户界面。每个服务器控件都包含一些成员对象,以便开发人员调用。例如,属性、事件和方法等。
3.1.1 Web标准服务器控件的功能
Web标准服务器控件是设计侧重点不同的另一组控件,它们不必一对一地映射到HTML服务器控件,而是定义为抽象控件。在抽象控件中,控件所呈现的实际标记与编程所使用的模型可能截然不同。例如,RadioButtonList控件可以在表中呈现,也可以作为带有其他标记的内联文本呈现。因此,它除了具有HTML服务器控件的所有功能(不包括与HTML元素的一对一映射)外,Web服务器控件还提供以下附加功能:
❑功能丰富的对象模型,该模型具有类型安全编程功能。
❑自动浏览器检测,控件可以检测浏览器的功能并呈现适当的标记,让你在设计时不用担心浏览器的兼容性。
❑部分控件可以使用Templates定义自己的控件布局。
❑部分控件可以指定控件的事件是立即发送到服务器,还是先缓存然后在提交该页时引发。
❑支持主题,你可以使用主题为站点中的控件定义一致的外观。
❑可将事件从嵌套控件(例如表中的按钮)传递到容器控件。
注意 在运行ASP.NET网页时,Web标准服务器控件使用适当的标记在页中呈现,这通常不仅取决于浏览器类型,还与对该控件所做的设置有关。例如,TextBox控件可能呈现为input标记,也可能呈现为textarea标记,具体取决于其属性的设置。
3.1.2 与HTML服务器控件的区别
虽然HTML服务器控件与Web标准服务器控件都是ASP.NET服务器控件,并且也都提供许多相似的功能。但从本质上讲,它们存在着许多不同之处,了解这些不同之处可以让我们在以后的实际开发中做出合理的选择。
1)是否映射到HTML标签。HTML服务器控件与HTML标签存在一一对应的映射关系,runat=server属性把传统的HTML标签转换成服务器控件,这使得开发人员可以将传统的ASP页面移植到ASP.NET平台上;而Web标准服务器控件不直接映射到HTML标签,而是根据客户端的情况生产一个或者多个HTML控件,这使得开发人员可以更好地使用第三方的控件。
2)是否能自适应输出。HTML服务器控件不可以自动根据浏览器的不同,调整所输出HTML文档的显示效果;而Web标准服务器控件隐藏了客户端的不同,它能够根据浏览器的不同,自动调整所输出HTML文档的显示效果。这样程序员可以把更多的精力放在业务上,而不用去考虑客户端的浏览器是IE还是Firefox,又或者是移动设备等。
3)对象模型的采用。HTML服务器控件使用了基于HTML中心对象模型,在该模型中,控件包括一个关键字/值对的属性集合;而Web标准服务器控件使用基于组件的对象模型,该模型要求使用一致对象类型,因此很适合面向对象编程的程序员。
4)编程与可扩展性。HTML服务器控件位于System.Web.UI.HtmlControls命名空间中,每个控件公开的属性与方法有限,可扩展性不是很好。而Web标准服务器控件位于System.Web.UI.WebControls命名空间中,提供更加统一的编程接口,很容易在它的基础之上扩展其他功能。并且Web标准服务器控件可以保存状态到ViewState里,这样页面在从客户端回传到服务器端或者从服务器端下载到客户端的过程中都可以保存。
5)事件处理模型。HTML服务器控件的事件处理都是在客户端的页面上,它是由页面来触发的;而Web标准服务器控件则是由页面把Form发回到服务器端,由服务器来处理。
来看这样一个例子。首先在页面定义了一个HTML服务器控件test,该控件不包含任何事件。如下所示:
<input id="test"type="button"value="保存"runat="server"/>
此时,运行页面并单击“保存”按钮,页面不会回传到服务器端,因此不论怎么单击“保存”按钮,页面都没有任何反映。为什么会出现这种情况呢?其原因是没有为该按钮定义鼠标单击事件。现在就来为它添加一个onserverclick事件,代码如下所示:
<input id="test"type="button"value="保存"
runat="server"onserverclick="Test_Click"/>
在后台定义Test_Click事件代码如下:
protected void Test_Click(object Source, EventArgs e)
{
Response.Write("我是保存按钮的事件");
}
再来运行页面并单击“保存”按钮,页面会发回服务器端,并执行protected void Test_Click(object Source, EventArgs e)事件,最后向页面输出“我是保存按钮的事件”。
为了更好地与Web标准服务器控件对比,下面同样定义一个没有任何事件的Web标准服务器控件的保存按钮。代码如下所示:
<asp:Button ID="test"runat="server"Text="保存"/>
运行页面并单击“保存”按钮,你会发现页面会发回到服务器端,因此整个页面会刷新一次。
3.1.3 WebControl基类
在ASP.NET中,所有的Web服务器控件都定义在System.Web.UI.WebControls命名空间中,派生自WebControl基类。WebControl类派生自Control基类,因此它有许多属性和方法与HTML服务器控件相同。但相比之下,WebControl基类提供了一个比HTML服务器控件更为抽象、更一致的模型。表3-1展示了WebControl基类常用的基本属性,这些属性的大部分封装了CSS样式特性,使得Web服务器控件的外表配置起来更加简单、方便。
3.1.4 单位
Web服务器控件的宽度、高度和类似属性是以单位进行设置的。单位是以对象((Uit结构)的形式实现的,使用这些对象,可以通过多种方式指定值和度量单位。其中,Unit结构组合了一个数值以及某种度量单位(如px、%等),因此在给控件设置这些属性时,必须给数值加上这些度量单位(如px、%等)来指示单位的类型。
例如,下面这个例子中的TextBox控件高度为100px,宽度为当前浏览器窗口宽度的80%:
<asp:TextBox ID="TextBox1"Width="80%"Height="100px"runat="server"></asp:TextBox>
当然,也可以通过代码的形式来给基于单位的属性赋值。通常有三种方法:
1)直接使用Unit对象的构造函数。如下代码所示:
//默认为像素
TextBox1.Height=new Unit(100);
//设置单位
TextBox1.Width=new Unit("80%");
2)使用Unit类型的静态方法,其中:Pixel()用来提供以像素为单位的值,Percentage用来提供以百分比为单位的值。如下代码所示:
//像素
TextBox1.Height=Unit.Pixel(100);
//百分比
TextBox1.Width=Unit.Percentage(80);
3)可以创建一个Unit对象,并通过其构造函数以及UnitType枚举对其进行初始化。如下代码所示:
//像素
TextBox1.Height=new Unit(100,UnitType.Pixel);
//百分比
TextBox1.Width=new Unit(80,UnitType.Percentage);
通过上面的方法,还可以将同一个单位赋值给多个控件。如下代码所示:
Unit myUnit=new Unit(100,UnitType.Pixel);
TextBox1.Height=myUnit;
TextBox2.Height=myUnit;
TextBox3.Height=myUnit;
3.1.5 枚举
如果Web服务器控件属性的数据类型为基元类型,如String、Boolean或Numeric类型,那么只需将属性值指定给属性即可设置属性值。同样,如果属性值在枚举类中定义,可以只将该枚举指定到属性。这样,ASP.NET就可以基于属性的类型解析枚举。举例如下:
TextBox1.TextMode=TextBoxMode.SingleLine;
3.1.6 颜色
若要将一个Web服务器控件属性(例如BackColor属性)设置为一种颜色,则需要分配对Color对象的引用,Color属于System.Drawing命名空间。常用的方法有如下几种:
1)通过调用Color对象的FromArgb方法,使用RGB(red、green、blue)或者ARGB(alpha、red、green、blue)颜色值。其中,每个值都可以用一个整数来表示,如下面的代码所示:
int alpha=255;
int red=255;
int green=255;
int blue=0;
//RGB
Button1.BackColor=Color.FromArgb(red, green, blue);
//ARGB
Button1.BackColor=Color.FromArgb(alpha, red, green, blue);
2)通过调用Color对象的FromName方法,将颜色名称作为字符串传递给它。注意,这里的颜色名称必须是系统存在的、能够识别的颜色名称。如下面的代码所示:
Button1.BackColor=Color.FromName("Red");
3)通过调用Color类的只读颜色属性值。如下面的代码所示:
Button1.BackColor=Color.Red;
4)通过调用ColorTranslator类的FromHtml方法,将颜色名称作为字符串传递给它。如下面的代码所示:
Button1.BackColor=ColorTranslator.FromHtml("Red");
除了上面这些方法外,也可以使用颜色名称或者十六进制数字(格式为#<红><绿><蓝>)来表示颜色值直接设置在控件里面。如下面的代码所示:
<asp:Button ID="Button1"BackColor="Red"runat="server"Text="Button"/>
<asp:Button ID="Button2"BackColor="#0066CC"runat="server"Text="Button"/>
3.1.7 字体
Font属性完整地引用了FontInfo对象,它定义在System.Web.UI.WebControls命名空间中。每个FontInfo对象都有若干个属性,用来定义字体的名称、大小与样式等,如表3-2所示。
在实际开发中,可以根据需要在代码中给不同的字体属性赋值。如下面的代码所示:
Button1.Font.Name="微软雅黑";
Button1.Font.Bold=true;
在这里需要注意的是,赋给Name属性的名称必须是系统存在字体名称。当然,也可以使用Names属性来代替Name属性,来提供一个可能的字体列表。Names接受一个名字数组集合,表现为一个有序的列表,具有最高优先权的名称在列表的最前面。如下面的代码所示:
string[]fontName={"微软雅黑,宋体,黑体"};
Button1.Font.Names=fontName;
注意Names属性和Name属性必须保持同步,设置任何一个都会影响另外一个。当设置Names属性时,Name属性自动设置为Names数组的第一个元素。当设置Name属性时,Names属性自动设置为只包含单个属性的数组。因此,为了减少冲突,只需要设置其中一个属性即可。
还可以使用FontUnit类型来设置字体的大小。如下面的代码所示:
//方法一
Button1.Font.Size=FontUnit.XSmall;
//方法二
Button1.Font.Size=FontUnit.Point(16);
<asp:Button ID="Button2"BackColor="#0066CC"runat="server"Text="Button"/>
除了在代码里进行设置,也可以直接在控件里面设置这些属性。如下面的代码所示:
<asp:Button ID="Button1"Font-Names="微软雅黑"Font-Bold="true"
Font-Size="X-Small"Text="保存"runat="server"/>
3.1.8 默认按钮
默认按钮是ASP.NET引入的一个新的机制,当页面有一个或者多个按钮的时候,它允许你在页面上指定一个默认按钮。当按“Enter”键时就触发这个默认按钮的事件处理程序。这样,无论用户在任何时候按“Enter”键,页面将会被回送,默认按钮的事件处理程序将会被触发。默认按钮的设置很简单,你只需要把From的DefaultButton属性设置成按钮控件的ID即可。如下面的代码所示:
<form id="form1"runat="server"defaultbutton="Button1">
<div>
<asp:Button ID="Button1"runat="server"Text="保存"onclick="Button1_Click"/>
<asp:Button ID="Button2"runat="server"Text="取消"onclick="Button2_Click"/>
</div>
</form>
上面的代码中,将Button控件Button1设置成了默认按钮,只要你按“Enter”键就会触发Button1的OnClick事件Button1_Click,从而进行相应的程序处理。
值得注意的是,默认按钮必须是实现IButtonControl接口的控件。这个接口由Button、LinkButton和ImageButton控件实现,因此,它们都可以作为默认按钮。