春鱼·编程观点

技术在进步, 世界在变得美好...

导航

Custom Control 设计初论

[引言]
ASP.NET第一次使开发控件成为每个程序员都可以做到的事情。开发一个好用的并且功能封装得很好的控件不再是只有前大的团队才可以做的事情。尽管这样,一些商业化的公司发布的产品还是功能强大得吓人, 但是价格也够吓人的。做为个人或者小型的团队,能够发布一些实用的,小型的,简单的控件还是挺让人兴奋的。以下仅谈以下作者对Custom Control设计上的认识和一些应用经验。

什么是Custom Control?
我常常把Custom Control和JSP的TAGLIB相提并论。其实在我看来二者有很多相似之处-设计思想上的类似。我是这样理解Custom Control的:

1. 以dll形式发布,可直接使用。
2. 在HTML中做为特殊的服务器端标记出现
3. 可通过编程设置其状态
4. 拥有POST数据处理能力
5 可引发后端事件
5. 分为可视化和非可视化 其中可视化输出目标HTML, 非可视化仅完成某些实用功能。
6. 可通过HTML ATTRIBUTE或者编程设置其特性


(本文偏向于介绍可视化控件,特别是实用型小控件)

以上第4条特别重要,因为既然是做为服务器端的标记,就必须在数据回发的时候可以用代码捕捉到该对象的状态变化或者活动。

设计Custom Control的目的是简化编码的工作量。注意,这里提供的便利不仅仅针对于眼前的项目,也许对世界上所有程序员有会带来遍历。与ASCX不同的是,Custom Control是跨工程和语言使用的。

我以前设计过一个小型的和比较简单的DatePicker Custom Control. 可以在输入日期类型的数据的时候弹出一个小型的漂亮的日历。用鼠标选取一个日期之后可以自动将日期按照格式写到网页上的控件中。避免了人工输入的格式校验等麻烦事。这个控件输出的目标HTML非常简洁。甚至仅仅输出了一个HTML记号。实际上我把所有的工作都交给客户端浏览器处理的。弹出日历这个过程用到的脚本被我封装到了一个HTC文件中,还有必须的一些图片,数据等等全部在客户端。这里的客户端容易产生误解。是针对VB代码而言的客户端。其实脚本资源和其他静态资源都放置在远端服务器上,只是设法在客户端调用。
有的朋友可能会问为什么要这样做。

第一。不希望控件产生的HTML污染了用户的页面。有的开发人员对代码的整洁干净与否有着特别敏感的情绪。特别讨厌一些设计比较差的控件产生的大段的,杂乱的脚本。如果我们开发HTML, 我们绝对不会写这么乱,而是将脚本与HTML分开。另外,减少输出的HTML同时也可以在一定程度上提高性能。
第二。将脚本逻辑与VB逻辑隔离开,隔离二者便于维护各自功能。有时候(大部分机会)我们只需要更改支持的脚本或者HTC,而不需要重新编译VB.
第三。当页面上出现多个相同控件时,优势更明显了。你一定不难想想页面上有一堆一摸一样的脚本会是什么样的场面。

举一个最简单的例子来说。你的工程里需要一组按钮。(很少有工程不需要按钮)。但是你的品味决定了你绝对不会将就HTML缺省的那个灰灰的按钮,样子难看,缺乏创意。你可以很方便得使用CSS来格式化一下你所有的按钮。但是你还是不满意。你想要的按钮要会随着鼠标靠近发生变化来取悦你的用户。比如鼠标靠近的时候变亮。鼠标按下去变暗。这个也可以通过给按钮设置DHTML Behavior实现。这个时候你的BOSS提出来。这样的按钮好。但是应该在这个模块变红色系列,在另一个模块变蓝色系列。你慌了。这个时候, 你就需要设计Button Custom Control了。除非你不觉得给控件设置一系列CLASS麻烦。而且开发好了之后,你可以拿出来卖。相信会有不少BOSS感兴趣。

让按钮随鼠标变色不难办到。只要你需要,我可以给你免费提供HTC源码。只要给按钮设置Style=“Behavior:url(...htc)“ 就可以了。现在想一想我们要设计的控件应该是什么样子。就像上面列出的:

1 编译成一个DLL
2 在ASP.NET页上以自定义的标记出现
3 可以通过HTML Attribute设置如何响应鼠标动作或者鼠标靠近了究竟变什么颜色。
4 输出到HTML中必须可以找到所需要的脚本和其他资源
5 必须能像后端引发事件。 即必须向普通按钮一样可以引发Click事件。不能光好看。

到这里, 你也许已经知道要完成什么工作。必须创造一个类,派生自System.Web.UI.WebControls.WebControl。 必须重写Render方法。 Render是最关键的方法 。是控件输出HTML的过程。在写这个方法之前。 你最好头脑中有一个基本的想法。控件生成的HTML是个什么样,如何在前台工作。通常有HTC的支持, 你需要发送到客户端的HTML应该不会很多。

公开的特性很重要。这关系到你的控件会有多少人喜欢,或者会卖多少钱。你至少要让你的客户程序员们可以控制按钮变色的方式。或者鼠标靠近的时候是变色,还是鼓起来,还是发出声音,还是跑到另一个地方?你可以把这些属性保存在私有成员里。在Render方法里一并输出给客户端,例如Button类有一个特性是ColorScheme。这个值确定了一系列颜色组,分别是按钮在MouseOver, MouseDown, MouseUp, MouseOut的时候的颜色。你的VB程序只需要将这个特性照原样输出到客户端。然后跟你的开发HTC或者脚本的伙伴说:去实现吧。另一些特性就需要你来处理。总之这个平衡要视乎成员的意志坚强与否。总之要让逻辑上灵活性更高。

另外你必须告诉客户端那个可怜的HTML如何寻找自己的资源。一般我会给Button加上一个特性。ResourcePath,这是一个字符串,表示资源相对于当前页的相对路径。然后把写好的脚本,图片和其他静态资源打包给用户。告诉他们,把这些东西解开拷贝到服务器WEB某个目录下,然后把这个路径设置到控件上。

输出到客户端的HTML大体上是这个样子:
<TimeLine:Button ColorScheme=“xp“ />

(以上是HTML的Custom Tag,需要将htc提前引入到页面中。)

另外你必须想办法让控件可以向后端引发事件。我一般是给控件附加一个看不见的FORM域。让发送到后端的数据可以被这个方法自己处理。这个问题再展开谈的话篇幅会变得很长。这篇文章多少涉及了一点:http://www.cnblogs.com/jayxu/archive/2004/03/26/4252.aspx 注意,在弄懂这个问题前, 先不要尝试动手开发。因为这样做出来的东西肯定不能用。MSDN文档很详细的解释了这个问题。请按索引“引发服务器事件”查找。

其他想法。当你的控件开发完毕。(熟练的朋友可能用不了一天)。你可以只需写一个类似<asp:Button />的标记就可以使用你的控件了。

进一步扩充。你可以为你的Button增加AutoPostBack特性。如果设置为false,那么即使单击按钮也不会将页面发回,这个时候你有可以给Button加上OnClick属性(不同于事件Click),设置客户端Click时处理这个动作的脚本过程。

Button有点简单。但是可以做为入门的范例研究。作者有不少类似作品。只要有时间,还是很乐意再写文章分析的。 作者偏向于应用,基本功不强。欢迎广泛批评。

电子邮件: xujian(a)nwpu.edu.cn
MSN: xchunyu(a)msn.com

posted on 2004-04-07 03:22  春鱼  阅读(3886)  评论(6编辑  收藏  举报