这次,我们就继《动态创建Web控件制做计算器》的文章,把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;
}
