多数在表示层应用的服务器控件主要由两个部分组成:服务器端功能和客户端功能。服务器端功能永远是服务器控件的核心,而随着技术的发展,客户端功能也逐渐变得越来越重要。只有两个部分互相配合,才能创建出功能强大、界面丰富的服务器控件。今天我们将对于在服务器控件中如何引用客户端功能做个简单的介绍。首先,什么是客户端功能,在Web编程中,客户端功能传统上是由Web页开发人员负责,并且不被封装在服务器组件中。ASP.NET脱离了这一范畴并使服务器控件能够发出客户端脚本,从而使服务器控件能够将客户端处理与服务器端处理结合起来。实现客户端功能对于提高服务器控件的交互性和可扩展性的意义重大。例如,常见的TreeView、TabStrip、ToolBar控件等,这些优秀的服务器控件具有很强的交互性和丰富的用户界面,而这些特征的实现与客户端功能是密不可分的。
实现客户端功能的技术主要是客户端脚本(JavaScript、VBScript等)和DHTML。因此,作为一名合格的开发人员必须具有熟练应用这些技术的能力。除此之外,还要掌握将客户端功能与服务器控件密切结合的方法。这些内容包括:实现简单客户端功能、实现复杂客户端功能、部署客户端脚本文件的方法。
一、客户端功能的简单使用。
实例一 简单客户端功能的实现。该实例实现一服务器端按钮,执行简单的客户端脚本。服务器控件生成代码如下:
using System.Collections.Generic;
using System.ComponentModel;
using System.Text;
using System.Web;
using System.Web.UI;
using System.Web.UI.WebControls;
namespace my.ComBox
... {
[DefaultProperty("Text")]
[ToolboxData("<{0}:UserClientFunction runat=server></{0}:UserClientFunction>")]
public class UserClientFunction : WebControl
...{
[Bindable(true)]
[Category("Appearance")]
[DefaultValue("")]
[Localizable(true)]
protected override void RenderContents(HtmlTextWriter output)
...{
output.AddAttribute(HtmlTextWriterAttribute.Type, "button");
output.AddAttribute(HtmlTextWriterAttribute.Value, "单击此按钮执行客户端功能");
output.AddAttribute(HtmlTextWriterAttribute.Onclick, "window.confirm('恭喜你!测试成功!');");
output.RenderBeginTag(HtmlTextWriterTag.Input);
output.RenderEndTag();
}
}
}
< %@ Register TagPrefix ="ClientScriptTest" Assembly ="ComBox" Namespace ="my.ComBox" % >
<! DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd" >
< html xmlns ="http://www.w3.org/1999/xhtml" >
< head runat ="server" >
< title > 无标题页 </ title >
</ head >
< body >
< form id ="form1" runat ="server" >
< div >
< ClientScriptTest:UserClientFunction runat ="server" ></ ClientScriptTest:UserClientFunction >
</ div >
</ form >
</ body >
</ html >
执行效果如下图所示
二、使用复杂的客户端功能(ClientScriptManager类提供的方法)
.NET 2.0框架ClientScriptManager类中提供了将客户端脚本文件加入服务器控件所需的必要方法,开发人员可以通过调用Page类的ClientScript属性来获取ClientScriptManager类实例。该类用于管理脚本、注册脚本和向页添加脚本。下面将介绍如何使用ClientScriptManager类中的RegisterClientScriptBlock和RegisterClientScriptInclude这两种方式注册客户端脚本,ClientScriptManager中其他方法的使用目前本人还没有使用过暂时不在此]叙述。
(1)注册脚本库(js文件)
RegisterClientScriptInclude 方法
(2)发出位于页面顶部和尾部的脚本
RegisterStartupScript 方法 和 RegisterClientScriptBlock 方法
(3)确保脚本块在页面只出现一次
以Is带头Registered结尾的四个方法
(4)将控件事件处理程序与客户端提交事件关联起来
RegisterOnSubmitStatement 方法
(5)注册一个数组用来存储控件自身变量
RegisterArrayDeclaration 方法
(6)注册一个隐藏域
RegisterHiddenField 方法
实例二:使用ClientScriptManager类中的RegisterClientScriptBlock注册客户端脚本。RegisterClientScriptBlock方法向页的顶部添加一个脚本块。以字符串形式创建脚本,然后将其传递给方法,方法再将脚本添加到页中。可以使用此方法将任何脚本插入到页中。请注意,脚本可能在所有元素完成之前呈现到页中;因此,您可能无法从脚本中引用页上的所有元素。在服务器控件开发中使用注册前台脚本的需要重写OnPreRender方法,具体实现代码如下:
using System.Collections.Generic;
using System.ComponentModel;
using System.Text;
using System.Web;
using System.Web.UI;
using System.Web.UI.WebControls;
namespace my.ComBox
... {
[DefaultProperty("Text")]
[ToolboxData("<{0}:UserClientFunction runat=server></{0}:UserClientFunction>")]
public class UserClientFunction : WebControl
...{
protected override void OnPreRender(EventArgs e)
...{
StringBuilder S = new StringBuilder(String.Empty);
S.Append("<Script type=text/javascript>");
S.Append(" function usingClientscript(obj){");
S.Append(" alert('你所输入的内容是:'+obj.value)");
S.Append("}");
S.Append("</Script>");
//使用Page.ClientScript获取ClientScriptManager实例。
ClientScriptManager curClientScriptManager = Page.ClientScript;
//注册脚本块。
curClientScriptManager.RegisterClientScriptBlock(this.GetType(), "TestClient", S.ToString());
}
protected override void RenderContents(HtmlTextWriter output)
...{
output.AddAttribute(HtmlTextWriterAttribute.Type, "text");
output.AddAttribute(HtmlTextWriterAttribute.Id, "Textbox_"+ID);
output.RenderBeginTag(HtmlTextWriterTag.Input);
output.RenderEndTag();
output.AddAttribute(HtmlTextWriterAttribute.Type, "button");
output.AddAttribute(HtmlTextWriterAttribute.Value, "确定");
output.AddAttribute(HtmlTextWriterAttribute.Onclick, "usingClientscript(Textbox_"+ID+")");
output.RenderBeginTag(HtmlTextWriterTag.Input);
output.RenderEndTag();
}
}
}
注意:以上代码使用了StringBuilder一般的对与相对较短的字符串来讲最好不使用StringBuilder,当字符串过长时使用,否则得不偿失。
前台对控件的调用同实例一,在此不再重复,引用后执行效果如下图所示:
实例三 使用使用ClientScriptManager类中RegisterClientScriptInclude 方法注册脚本库。RegisterClientScriptInclude 方法与 日egisterClientScriptBlock 方法类似,但此方法将添加引用外部 .js 文件的脚本块。包含文件在任何其他动态添加的脚本之前添加;因此,您可能无法引用页上的某些元素。在此对在自定义控件中如何引入js文件简单的介绍.
首先,我们要准备一Js文键Candar.js功能是生成一个日历显示控件,在控件测试工程下新建一个文件夹,命名为mycontrols,在此文件夹新建一js目录用于存放引入的js文件Candar.js则js文件所在路径为“mycontrols/js/Candar.js”使用RegisterClientScriptInclude 注册此脚本文件控件代码如下:
using System.Collections.Generic;
using System.ComponentModel;
using System.Text;
using System.Web;
using System.Web.UI;
using System.Web.UI.WebControls;
namespace my.ComBox
... {
[DefaultProperty("Text")]
[ToolboxData("<{0}:FirstCarder runat=server></{0}:FirstCarder>")]
public class FirstCarder : WebControl
...{
protected override void OnPreRender(EventArgs e)
...{
ClientScriptManager curManager = Page.ClientScript;
curManager.RegisterClientScriptInclude(this.GetType(), "Carder", "My Controls/JS/Carder.js");
StringBuilder S = new StringBuilder(string.Empty);
S.Append("<script type=text/javascript>");
S.Append("calendar();");
S.Append("startclock();");
S.Append("</script>");
curManager.RegisterStartupScript(this.GetType(), "next", S.ToString());
base.OnPreRender(e);
}
protected override void RenderContents(HtmlTextWriter output)
...{
StringBuilder s=new StringBuilder();
s.Append("<style type="text/css">");
s.Append(" <!--");
s.Append(".today{font-size:9pt;Color:#330099};");
s.Append(".thead{font-size:9pt;color:#ffffff;background-color:#1E70A8;}");
s.Append(".whiteword{font-size:9pt;Color:White};");
s.Append(".nday{font-size:9pt;font-family:Arial;font-weight:bold;Color:#330066};");
s.Append(".clock{border: 1px solid #0000ff; height:17px;background-color:#ffffff;width:75px;font-size:10pt;color:#330066};");
s.Append("-->");
s.Append("</style>");
output.Write(s.ToString());
}
}
}
前台调用代码同实例一。本例中同时使用了RegisterStartupScript方法,其作用是向页中添加一个脚本块,该脚本块在页完成加载后引发页的 onload 事件之前执行。该脚本通常不创建为事件处理程序或函数;它通常只包含要执行一次的语句。