回调示例 以下 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. 回调请求输出 |
图 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)内的行为。