利用ASP.NET 2.0创建自定义Web控件
回调示例
以下 Web 页使用回调机制查询服务器以获得其当前时间。该页面弹出一个 JavaScript 警告,在无需完整页面回发的情况下显示当前时间。
<%@ Page Language="C#" CompileWith="Default3.aspx.cs" ClassName="Default3_aspx" %>
<%@ Register TagPrefix="cc1" Namespace="MyControls" Assembly="WebControlLibrary3" %>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN" "http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" >
<head runat="server">
<script language="javascript">
function GetServerTime() {
var message = ’’;
var context = ’’;
<%=CallBack%>
}
function ShowServerTime(timeMessage, context) {
alert(’The time on the server is:\n’ + timeMessage);
}
function OnError(message, context) {
alert(’An unhandled exception has occurred:\n’ + message);
}
</script>
</head>
<body>
<form id="form1" runat="server">
<div>
<cc1:timesnap id="TimeSnap1" runat="server"> </cc1:timesnap>
<input type="button" value="GetTime" onclick="GetServerTime();" />
</div>
</form>
</body>
</html>
上述页面源代码包含三个关键 JavaScript 函数:GetServerTime()、ShowServerTime() 和 OnError()。这些 JavaScript 函数与页面的 GetCallbackEventReference 带外请求相关联。
public partial class Default3_aspx {
public string CallBack;
void Page_Load(object sender, EventArgs e) {
CallBack = this.GetCallbackEventReference(TimeSnap1,"message","ShowServerTime","context","OnError");
}
}
GetCallbackEventReference 方法需要为其第一个参数实现 ICallbackEventHandler 接口的对象。通过实现 RaiseCallbackEvent() 方法,TimeSnap 自定义服务器控件符合接口要求。
public class TimeSnap : WebControl, ICallbackEventHandler
{
...
public string RaiseCallbackEvent(string eventArgument) {
// Uncomment next line to test error handler
// throw new ApplicationException(// "Some unhandled exception");
return DateTime.Now.ToLocalTime().ToShortTimeString();
}
}
}
TimeSnap.RaiseCallbackEvent() 方法仅返回 string 格式的当前时间。
图 9 说明了按下 GetTime 按钮的结果。向服务器发出带外请求,从而产生显示服务器上当前时间的“Alert”窗口。发出这个请求不需要回发,因此控件的最初生成时间不会改变。
使用设计器
在前面的示例中,我们已经使用了几个标准的特性来规定自定义控件的属性将与设计器 (Visual Studio) 进行交互的方式。我们为各种控件属性分配了特性以定义属性将在其中出现的类别、定义属性是否应该具有一个默认值、定义属性的说明应该是什么样子以及属性是否应该为 bindable。在 ASP.NET 1.x 中,附加的设计器类 使您可以创建用于编辑属性的新对话框、自动将属性值从 String 转换为其他数据类型(反之亦然),并显示只在运行时生成的控件的占位符数据。
设计器类有助于将控件开发分成两个阶段。第一,您必须开发自定义控件。第二,您必须决定开发人员将如何与设计环境内的控件进行交互。设计器类通过在每个自定义控件的顶部充当装饰师来完成第二个任务。换句话说,如果您要开发很多自定义控件,您可以创建一个标准的可重复使用的设计器集,并通过特性简单地将设计器应用到每个自定义控件中。
ASP.NET 2.0 为设计器模型提供了几项增强功能:
1) 新的复合控件设计器 — CompositeControlDesiger 类完全识别复合控件,并且提供支持父子控件关系的功能。
2) 新的数据绑定控件设计器 — DataBoundControlDesigner 为 Databound 控件提供了很多新功能。您可以使用该设计器来提供模拟数据,或者在设计期间自动连接到活 datasource。
3) 增强的备用设计时区域支持 — 新的 DesignerRegion 类及其子类提供了一种非常灵活的机制以便显示控件。您可以使用 DesignerRegion 来设置控件的选项卡式视图。您还可以使用 EditableDesignerRegion 控件为控件创建新的模板。
4) 增强的模板支持 — 现在,设计器类提供了更简洁的机制以便将新的模板添加到控件中。模板化控件是一种将控件逻辑和控件显示分开的控件。显示通过模板进行定义,而逻辑在实际控件中进行编码。
5) 增强的任务支持 — 现在,设计器可以合并设计时的任务。最常见的任务将可在视图之间切换。但是,其他任务可以包括控件的自动配置或资源文件的自动创建。任务可以在设计时控件上显示为菜单(与允许您配置 GridView 控件的菜单相似)。
6) 增强的事件支持 — 设计器中的事件模型已经进行了改进。现在,您可以创建事件来响应在不同区域中的单击或对各种任务的单击。使用设计器时,只要用户在特定区域上单击就可以使控件切换视图、自动生成代码或更改配置。
ASP.NET 2.0 具有一个经过显著改进的设计器模型,它可以使专业控件开发人员的工作更加简单。如果您只是为自己使用而构建一个单个的控件,该设计器就大材小用了。但是,如果您要为分发而构建一个控件,您可以使用新的设计器来全面地自定义 Visual Studio 2005 中控件的行为。
小结
尽管 ASP.NET 2.0 包含了一个内容丰富的扩展控件集,但开发人员通常有很多理由来创建自定义控件。由于 ASP.NET 2.0 中的增强功能,创建自定义控件的过程要比在 ASP.NET 1.x 中更快、更容易。新的 CompositeControl 基类完全利用自适应呈现模型,并为创建复杂的控件提供了一个简单、易于使用的容器。如果您的控件需要回发或回调功能,ASP.NET 2.0 简化了处理客户端脚本文件和开发带外请求的过程。最后,在您开发控件后,您可以使用各种设计器类来完全配置控件在可视化设计器(例如 Visual Studio 2005)内的行为。