Developing ASP.NET Custom Control With C# Builder
不知有多少人还记得当初撰写Windows 3.1 程序时的情况,100 多行程序码, 只为了在画面上秀出一个视窗, 如果要在视窗上加上一个TextBox, 那么又再得加上几行程序码, 其步骤之繁杂足以让许多程序设计师放弃往Windows 上移动。随着物件导向设计的进化脚步,这些折磨人的工作也慢慢的简化了, 借着Framework( MFC、OWL)的帮助,只要1-20 行程序码就能完成以往那1-200 行程序码的工作。但是如同大部份的进化模式一样,齿輪一旦转动了, 向前走就是唯一的道路。人们开始发现, 光是Framework 是不够的,她们需要更大生产力的工具才能以更快的速度设计出应用程序, 于是乎Visual Basic 出现!!正式的敲开了RAD 时代的大门, 程序设计师只要动动滑鼠、设设属性, 一行程序码都不用写就可以做到原本要写1-20 行的应用程序才能完成的功能,也不用一直重复执行程序來调测画面,因为所見即所得正是RAD 的特色之一。Visual Basic 开启了一个崭新时代,也启动了继Framework 之战后的另一场开发工具战役,强敌DELPHI 装备着同样的武器及强大的资料库支援加入了战场,并以自身独有的执行效率优势不停的往Visual Basic 先天的直译弱点攻击。直至今日,DELPHI 与Visual Basic 的領地互有消长, Windows 上的战争也慢慢趋向平淡。随着Internet 的普遍化,企业开始要求将原本在Windows 上的系统转移到Web 上, 这时人们开始发现,以往用來建构小型Web 系统的CGI、ASP、PHP的生产力不足以满足移转大型系统的需求,于是进化齿輪再一次的转动,RAD 以Web 的面容出现在人们眼前,再一次证明舞动滑鼠也可以写Web 程序,她的名字是AS P.NET。当然,将ASP.NET 与RAD 相提并論似乎有点不对称,因为RAD 属于开发工具层面,而ASP.NET 则是语言层面, 但不可否认的是这兩者共同实现了人们以RAD 方式撰写Web 程序的梦想。既然是RAD, 那么舞动滑鼠、拉拉元件、设设属性也是常态, 但期望着开发者为你预先建立好所有元件是不实际的, 总有些时候我们得自己动手做些元件,这是本文的主要目的,让我们开始这一趟旅程吧。
What's ASP.NET Custom Control
在一开始, 元件这个名词的涵意指的是一个具备良好封装、低藕合性、可独立运作的程序单元, 随着元件化设计模式的普及化,这种过于广泛的定义慢慢被切割成兩部份。一部份仍旧沿用元件之名,但其涵意已挶限在不含UI 介面上,另一部份则使用Control 之名, 指的是仅具备UI 能力的元件。在ASP.NET 上, 程序设计师大部份撰写的是后者, 也就是Custom C ontrol,她可以被安装在RAD 开发工具的元件盘中,使用者可藉由滑鼠拖放來使用她。不管是元件还是Co ntrol,其基本的要素是相同的,那就是Pr operties、Methods、Events。Properties 指的是Control/Component 的狀态,例如Control.ControlState 代表着该Control 目前的狀态是处于初始化或是绘制中,Methods 代表的是某一个动作, 例如Control.RenderControl 会将该Control 绘制到HtmlTextWriter 中,Events 则是代表着目前元件的狀态发生了什么变化, 或是用來通知某个动作即将执行或是执行完毕。这三个要素共同组成了一个Control/Compon ent,也间接的提供了RAD 工具一个通道來与Control/Component 互动。使用.NET相容语言实作这三个要素是件简单且再自然不过的事,因此重点就落在于如何撰写ASP.NET Custom Control 上了,ASP.NET 要求所有的Custom Control 必须继承至System.Web.UI.Control 亦或是其子類别System.Web.UI.WebControls.WebControl,兩者之间的差别在于System.Web.UI.Control 仅具备了一个Custom Control 所需的基本功能,WebControl 则同时具备Custom Control 的基本功能及Rending Style 的能力, 大部份的情况下设计者都会选择直接继承至WebControl 或是其子類别(TextBox、CheckBox),这样做可以省下自行撰写Rending Style 的工作。当设计者需要自行处理Rending Style 或是不需要此能力时,那么直接继承至Control 就是明智的选择。
First Custom Control : NumberEdit
在许多线上购物的网页中常会遇到要输入信用卡号码的对话框, 某些设计较良好的网页会限制该对话框仅能接收數字部份的输入, 这一节中所撰写的就是这一种Control 。在开始之前! 首先得先了解这是如何做到的?无庸置疑!这个Control 一定是TextBox,HTML 中的TextBox 拥有一个名为onKeyPress 的JavaScript 事件, 此事件会在使用者键入某个字元至TextBox 时触发,只要欄截这个事件,那么限制使用者的输入就不是问题了,程序1 是完整的JavaScript 程序码 程序1)
讀者们可以看到程序中只接受keycode的0)与keycode>57(ASCII 的9)之间的输入,现在只要将这段JavaScript 结合TextBox 就可以完成这一节的NumberEditor Control 了(程序2 )。(程序2)
using System; using System.Text; using System.Web.UI; using System.Web.UI.WebControls;
namespace SmartSuite.Web.Editors
{ public class NumberEditor:TextBox {
private void RenderJavaScript(HtmlTextWriter output)
{ StringBuilder sb=new StringBuilder(); sb.AppendFormat(""); output.Write(sb.ToString());
}
protected override void AddAttributesToRender(HtmlTextWriter writer)
{ base.AddAttributesToRender(writer); writer.AddAttribute("OnKeyPress",String.Format("return
{0}_KeyPress_Handle(this);",base.ID)); }
protected override void Render(HtmlTextWriter output)
{ RenderJavaScript(output); base.Render(output);
}
} }
NumberEditor 选择直接继承至TextBox, 这可以省下从头撰写一个TextBox 的时间。让我们从Render 函式开始讨論起, 这个函式是由此Control 的Container Contro l(容器)所呼叫,
大多數情况下这个Conatiner Control 就是Page Control,Page Control 在呼叫子Control 的Render 函式时会传入一个HtmlTextWriter 物件, 子Control 可以利用这个物件來绘出Control 所对应的HTML 程序码。NumberEditor 利用了这个物件來绘出JavaScript 程序码, 接着串接父類别(TextBox)來绘出预设的TextBox HTML 程序码。为了将JavaScript 的onKeyPress 連结上NumberEditor, 程序中覆载了AddAttributesToRender 函式來完成这个动作,这个函式是WebControl 所独有的,她负责绘出HTML Tag 中的參數部份,例如Style 、Value、OnKeyPress、OnBlur 等等之類。
Debuging Custom Control
不管是使用那种工具撰写何种程序, 除错都是最重要的动作, 程序是人写的, 怎可能不出错呢?对Custom Control 除错与除错一般程序大致相同,只要在原先的ASP.NET Project Group 中加入Custom Control 的Project 即可完成准备动作(图1) 。
(图1)
接着只需设定想要程序停下的中断点即可(图2 )。 (图2)
更具实用性的Custom Control : Spin Edit
Spin Edit 在Windows 中是相当常用的Control, 通常是用來调整一个对话框中的數字,但是这种Control 在网页中并不多見, 这一节中将开发运行于网页上的Spin Edit Control。在开始之前!讀者们得先了解一个重点,Spin Edit并非是一个单一Control ,她是由