四、GetScriptReferences
这个方法负责在ScriptManager中注册JavaScript文件。在这个方法中,针对每一个要求的JavaScript文件,我们都需要创建一个相应的ScriptReference实例。例如,在图像按钮例子中,我们按如下方式注册JavaScript文件:
IEnumerable<ScriptReference> IScriptControl.GetScriptReferences() { return new ScriptReference(Page.ResolveUrl("~/SrvImageButton.js")); } |
此外,我们还可以以嵌入式资源方式注册JavaScript文件。为此,我们必须首先在Visual Studio的解决方案资源管理器中把一个JavaScript文件标记为一种嵌入式资源。然后,我们必须添加上WebResource属性以便利用Asp.Net 2.0 Web资源处理器。下列代码展示了如何把一个JavaScript文件注册为一个嵌入式资源:
[assembly: WebResource("MyControls.SubControl.Script1.js", "text/javascript")] namespace MyControls{ public class SubControl: Control, IScriptControl { //……… IEnumerable<ScriptReference> IScriptControl.GetScriptReferences() { return new
ScriptReference(this.Page.ClientScript.GetWebResourceUrl( this.GetType(), "MyControls.SubControl.Script1.js")); } } }
|
此外,如果我们想实现IScriptControl接口而不是从ScriptControl中继承的话,我们还必须重载OnPreRender与Render方法。这样将能确保ScriptManger识别出该服务器控件是一个支持Ajax功能的控件。
下列代码展示了开发基于ASP.NET 2.0服务器端控件的AJAX控件时必须在服务器端实现的最少代码:
using System; using System.Collections.Generic; using System.Web; using System.Web.UI; using System.Web.UI.WebControls; namespace DummyNamespace { public class DummyControl : Control, IScriptControl { public DummyControl(): base() {} protected override void OnPreRender(EventArgs e) { base.OnPreRender(e); ScriptManager scriptManager = ScriptManager.GetCurrent(Page); if (scriptManager == null) { throw new InvalidOperationException( "此页面中必须存在一个ScriptManager控件!"); } scriptManager.RegisterScriptControl(this); } protected override void Render(HtmlTextWriter writer) { base.Render(writer); writer.AddAttribute(HtmlTextWriterAttribute.Id, this.ClientID); writer.RenderBeginTag(HtmlTextWriterTag.Div); writer.Write("这是一个哑元控件"); writer.RenderEndTag(); if (!DesignMode) { ScriptManager.GetCurrent(this.Page).RegisterScriptDescriptors(this); } } IEnumerable<ScriptDescriptor> IScriptControl.GetScriptDescriptors() { //因为这仅是一个哑元控件,所以我们只是创建一个新的实例 return new ScriptControlDescriptor("DummyNamespace.DummyControl", ClientID); } IEnumerable<ScriptReference> IScriptControl.GetScriptReferences() { return new ScriptReference(Page.ResolveUrl("~/DummyControl.js")); } } }
|
上面代码中,我们在OnPreRender方法中实现注册控件,而在Render方法中注册脚本描述符部分。当然,如果页面上不存在ScriptManager控件的话,我们必须抛出一个错误提示。但是,如果你正在开发非基于ASP.NETAJAX框架的控件的话,你完全可以从页面中删除ScriptManager控件。
五、创建基于ASP.NET服务器端控件的增强AJAX图像控件
(一)创建示例AJAX网站
启动Visual Studio 2005,选择“文件→新建网站…”,然后选择“ASP.NET AJAX-Enabled Web Site”模板,命名工程为“AjaxServCtrlTest”,并选择C#作为内置支持语言,最后点击“确定”。
(二)创建AJAX技术支持的增强服务器控件
点击菜单“文件→添加→新建项目…”,在“添加新项目”对话框中,从左边选择“项目类型”为“Visual C#→Windows”,从右边选择“模板类型”为“Web控件库”,输入控件库的名字为AjaxImageButtonLib,选择目标目录为前面创建的网站根目录,最后点击“确定”。
接下来,根据我们前面的分析,把类库源WebCustomControl1.cs文件的内容更改为以下形式:
//…………(省略命名空间引用部分) namespace AjaxImageButtonLib { public class MySrvImageButton : System.Web.UI.WebControls.ImageButton, IScriptControl { public string HoverImageUrl { get { object value = ViewState["hoverImageUrl"]; return (value == null) ? string.Empty : (string)value; } set { ViewState["hoverImageUrl"] = value; } } public string ClientClickFunction { get { object value = ViewState["clientClickFunction"]; return (value == null) ? string.Empty : (string)value; } set { ViewState["clientClickFunction"] = value; } } public MySrvImageButton() : base() { } protected override void OnPreRender(EventArgs e) { base.OnPreRender(e); ScriptManager scriptManager = ScriptManager.GetCurrent(Page); if (scriptManager == null) { throw new InvalidOperationException ("ScriptManager required on the page."); } scriptManager.RegisterScriptControl(this); } protected override void Render(HtmlTextWriter writer) { base.Render(writer); if (!DesignMode) { ScriptManager.GetCurrent(this.Page).RegisterScriptDescriptors(this); } } IEnumerable<ScriptDescriptor> IScriptControl.GetScriptDescriptors() { ScriptControlDescriptor desc = new ScriptControlDescriptor("AjaxImageButtonLib.MySrvImageButton", ClientID); if (!string.IsNullOrEmpty(HoverImageUrl)) { desc.AddProperty("hoverImageUrl", HoverImageUrl); } if (!string.IsNullOrEmpty(ClientClickFunction)) { desc.AddEvent("click", ClientClickFunction); } yield return desc; } IEnumerable<ScriptReference> IScriptControl.GetScriptReferences() { yield return new ScriptReference(Page.ResolveUrl("~/SrvImageButton.js")); } } }
|
首先,我们注意到我们要创建的新控件MySrvImageButton继承自ASP.NET服务器控件ImageButton,并继承了接口IScriptControl。
有了前面的理论描述,在此,我们省略对于其中几个常规方法的描述。
接下来,我们要构建这个控件库(即程序集)。右击此库工程,并点击“生成”命令以生成程序集AjaxImageButtonLib.dll,此库文件中即包含了我们的服务器控件。