这次,我们就继《》的文章,把Web控件制作的就算器做成一个Web控件,首先,打开vs2005,文件/新建/项目,如下图:
在visual C#中选择Windows 在模版里面选择Web控件库,输入名称和存储位置,点确定。进入代码区以后,删掉默认的Text属性,开始写我们的代码,先修该一些必要的属性,以至于让我们自己做的控件像一个产品。
将控件类名字从默认的WebCustomControl1.cs改为CalculatorControl.cs,同时,代码里面的类名字也要改的和它一样,类上面的ToolboxData属性也要做响应的修改,改成[ToolboxData("<{0}:CalculatorControl runat=server></{0}:CalculatorControl>")],注意的是上面修改的三处的类名必须相同,如果不同写的控件将不能用。然后打开AssemblyInfo.cs文件,在命名空间中引入using System.Web.UI;在下面属性里加一个[assembly: TagPrefix("WebControlLibrary1", "liu")],其中第一个参数是工程的命名空间,第二个是控件以后拖动到网页上以后<>标签里面显示的名字,比如,我们第二个参数写成liu,控件拖动到网页上以后,就显示成<liu:CalculatorControl ID="CalculatorControl1" runat="server" />。完了以后可以根据需要,修改上面的公司名称,版权等属性做完这些工作开始写代码。
注意的是Web自定义控件的编写过程是不可视的,所有的控件、控件的事件都必须写代码来完成,初步规划编写的步骤:先写一个构造函数,在构造函数里面完成算器的界面的创建。然后再定义创建按钮的函数,和写按钮要响应的事件最后重写绘制的方法RenderContents。写完后,整个程序代码如下:
using System; using System.Collections.Generic; using System.ComponentModel; using System.Text; using System.Web; using System.Web.UI; using System.Web.UI.WebControls; using System.Web.UI.HtmlControls; namespace WebControlLibrary1 { [ToolboxData("<{0}:CalculatorControl runat=server></{0}:CalculatorControl>")] public class CalculatorControl : WebControl { //定义两个操作数 static double Num1; static double Num2; //记录操作符 static string OperatorF; //判断“=”是否被点击过,每次操作时清空上次操作的记录 static bool ReOperator = false; //容器,容纳所有控件 Panel CT = new Panel(); TextBox txtShow = new TextBox(); /**//// <summary> /// 构造函数,在此函数里面动态的创建计算器的界面 /// </summary> public CalculatorControl() { txtShow.Width = 95; CT.Controls.Add(txtShow); HtmlGenericControl htmlString = new HtmlGenericControl(); htmlString.InnerHtml = "<br>"; CT.Controls.Add(htmlString); for (int i = 0, I = 1; i < 3; i++) { string[] Op = { "+", "-", "*" }; string[] CharOp = { "jia", "jian", "cheng" }; for (int j = 0; j < 3; j++) { CT.Controls.Add(CreateBtn(I.ToString())); I++; } Button OperBtn = new Button(); OperBtn.Text = Op[i]; OperBtn.ID = CharOp[i]; OperBtn.Width = 25; OperBtn.Click += new EventHandler(Btn_Click); CT.Controls.Add(OperBtn); HtmlGenericControl htmlStr = new HtmlGenericControl(); htmlStr.InnerHtml = "<br>"; CT.Controls.Add(htmlStr); } CT.Controls.Add(CreateBtn("Backspace", "B")); CT.Controls.Add(CreateBtn("Clear", "C")); CT.Controls.Add(CreateBtn("deng", "=")); CT.Controls.Add(CreateBtn("chu", "/")); //自己定义的将控件添加到当前Web控件,没有这一步,上面创建的所有控件不会响应事件 this.Controls.Add(CT); } protected override void RenderContents(HtmlTextWriter output) { CT.RenderControl(output); } /**//// <summary> /// 创建操作数按钮的函数 /// </summary> /// <param name="Num">操作数</param> /// <returns>返回一个按钮</returns> public Button CreateBtn(string Num) { Button NumBtn = new Button(); NumBtn.Text = Num; NumBtn.ID = "ID" + Num; NumBtn.Width = 25; NumBtn.Click += new EventHandler(Btn_Click); return NumBtn; } /**//// <summary> /// 创建操作符按钮的函数 /// </summary> /// <param name="ID">按钮的ID号</param> /// <param name="Operator">操作符</param> /// <returns>返回一个按钮</returns> public Button CreateBtn(string ID, string Operator) { Button OperBtn = new Button(); OperBtn.Text = Operator; OperBtn.ID = ID; OperBtn.Width = 25; OperBtn.Click += new EventHandler(Btn_Click); return OperBtn; } /**//// <summary> /// 定义按钮响应的事件,所有按钮通用一个事件,用按钮的Text属性区分要执行的操作 /// </summary> /// <param name="sender"></param> /// <param name="e"></param> public void Btn_Click(object sender, EventArgs e) { string BtnText = ((Button)sender).Text; switch (BtnText) { case "+": Num1 = int.Parse(txtShow.Text); OperatorF = BtnText; txtShow.Text = ""; break; case "-": Num1 = int.Parse(txtShow.Text); OperatorF = BtnText; txtShow.Text = ""; break; case "*": Num1 = int.Parse(txtShow.Text); OperatorF = BtnText; txtShow.Text = ""; break; case "/": Num1 = int.Parse(txtShow.Text); OperatorF = BtnText; txtShow.Text = ""; break; case "=": if (OperatorF == "+") { Num2 = Num1 + double.Parse(txtShow.Text); txtShow.Text = Num2.ToString(); } else if (OperatorF == "-") { Num2 = Num1 - double.Parse(txtShow.Text); txtShow.Text = Num2.ToString(); } else if (OperatorF == "*") { Num2 = Num1 * double.Parse(txtShow.Text); txtShow.Text = Num2.ToString(); } else if (OperatorF == "/") { Num2 = Num1 / double.Parse(txtShow.Text); txtShow.Text = Num2.ToString(); } ReOperator = true; break; case "C": txtShow.Text = ""; Num1 = Num2 = 0; break; case "B": if (txtShow.Text.Length >= 1) { txtShow.Text = txtShow.Text.Substring(0, txtShow.Text.Length - 1); if (txtShow.Text != "") Num1 = int.Parse(txtShow.Text); else Num1 = 0; } break; default: if (ReOperator) { txtShow.Text = ""; Num1 = Num2 = 0; ReOperator = false; } txtShow.Text += BtnText; break; } } }} 和上一篇文章相比,这次我们在布局上减少了很多代码,这次没有用表格进行布局,而是创建了一个panel控件作为容器,然后把所有的控件都放在它的上面,引入了System.Web.UI.HtmlControls命名空间,用它里面的方法控制换行。Web控件就编写完了,先生成一下,再建立一个网页进行测试。
在解决方案上面单击右键,添加/新建网站,如图:
选择ASP.NET网站,选好存储路径,语言选C#,确定。进入页面以后,将网页设为起始页,在工具箱上单击右键/选择项,打开对话框,如下图:
点击浏览,选择我们刚生成的控件,点击确定,就将控件添加进工具箱了,如图:然后将控件拖放到网页上面,网页代码如下: <% @ Page Language="C#" AutoEventWireup="true" CodeFile="Default.aspx.cs" Inherits="_Default" %> <% @ Register Assembly="Calculator" Namespace="WebControlLibrary1" TagPrefix="liu" %> <! 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 > < liu:CalculatorControl ID ="CalculatorControl1" runat ="server" /> </ div > </ form > </ body > </ html > 运行进行测试,结果如下图:
这样一个Web自定义控件就制作完成了,虽然这个控件的功能很不完整,甚至连0 都没有,但是我在制作过程,还是遇到了一些困难,不如:更改控件拖放到网页上标签的名字,控件无法响应事件等等,解决了问题,也学到一些东西,不足的地方大家有兴趣可以完善。