<iframe align="top" marginwidth="0" marginheight="0" src="http://www.zealware.com/46860.html" frameborder="0" width="468" scrolling="no" height="60"></iframe>
(一). 概述
业余时间做了一个非常有用的控件,介绍一下.
一般当我们要实现这样一个计算功能页面:
TextBox1(单价)*TextBox2(数量)=TextBox3(总和);
并且当在TextBox1或TextBox2中输入数据,鼠标离开时,TextBox3控件能够即时重新计算新值(乘积).
一般我们的做法步骤是:
1.拖三个控件到页面上,默认三个TextBox控件ID分别为:TextBox1,TextBox1,
TextBox3.
2.写个JavaScript函数,能够计算TextBox1和TextBox2的乘积,并赋值给TextBox3
即时最新值.
scriptlanguage='javascript'>
functioncompute()
{
var_num=parseFloat(document.getElementById('TextBox1').value);
var_price=parseFloat(document.getElementById('TextBox2').value);
document.getElementById('TextBox3').value=_num*_price;
}
script>
3.注册TextBox1和TextBox2的onblur事件(TextBox控件失去焦点时触发).
this.TextBox1.Attributes.Add("onblur","compute()");
this.TextBox2.Attributes.Add("onblur","compute()");
OK,这样固然能够完成.也存在以下缺点:
1.不够通用,如果好多页面都需要这么一个控件,那得写上面这些代码到所有
页面中.开发效率不高.且容易出错.
2.页面中代码比较乱.嵌入好多JavaScript代码.难以维护.
3.假如运算表达式非常复杂[如:A*B+(B*C)+Math.E]每次设置JS也比较麻烦.
基于以上缺陷,
下面是一个通用的自定义控件AutoComputeControl(自动计算),能够弥补以上缺点,
且具有通用性,
特点如下:
1.使用简单,只需设置一个表达式属性Expression,控件能够自动完成所有JS脚本.
其中表达式由:运算符和变量组成(控件的ID),等一下会详细介绍使用方法.
2.不仅支持简单运算,更大的优势是支持复杂表达式,如:
price*(num+2*(3+6))*Math.E=sum,即
TextBox1*(TextBox2+2*(3+6))*Math.E=TextBox3
仅通过将控件的:ID和运算符任意组合成计算表达式赋值给控件Expression属性,
其它的工作由本控件来完成, 本控件能够自动生成所有JS脚本.并最终在页面客
户端呈现.
3.另外,支持Math对象下面的属性和方法:
Math属性:Math.EMath.LN10Math.LN2Math.LOG10EMath.LOG2E
Math.PIMath.SQRT1_2Math.SQRT2
Math方法:Math.abs(x)Math.acos(x)Math.asin(x)Math.atan(x)
Math.atan2(x,y)Math.ceil(x)Math.floor(x)Math.cos(x)
Math.exp(x)Math.log(x)Math.max(x,y)Math.min(x,y)
Math.pow(x,y)Math.random()Math.round(20.49)Math.sin(x)
Math.sqrt(x)Math.tan(x)
例如:Math.sin(Math.sqrt(price1*price2))+Math.E*num=sum
即Math.sin(Math.sqrt(TextBox1*TextBox2))+Math.E*TextBox3=TextBox4
4. 最终用户还可以在控件中输入表达式:
例如, 用户在TextBox1框中输入: 6*(5+2)
再在TextBox2中输入: 3+Math.E*Math.PI
再把表达式: TextBox1*(TextBox2+2*(3+6))*Math.E=TextBox3
赋值给本控件属性Expression, 仍然能够正确计算出结果.
5. 在一个页面中放多个本控件.
比如: 拖个本控件到页面跟 TextBox1/TextBox2/TextBox3组合,
再拖另一个控件跟另一组 TextBox4/TextBox5/TextBox5组合.
注意: 不要两组表达式产生冲突,比如把TextBox1即在第一组又在
第二组, 这样脚本生成是正确的, 但这样自动生成的客户端脚本, 会
为TextBox1注册两个onblur事件, 那么默认第二个onblur起效, 不能
同时起效. 这是JavaScript 语法规定的.
实现原理: 本自定义控件的Expression属性, 如: TextBox1*(TextBox2+TexBox3)*0.90=TextBox4
中包括:
1. 控件的ID. 2. 表达式之间的关系.
然后自定义控件内核代码会:
1. 用编译算法扫描表达式属性(Expression)值, 分析运算关系.
2. 根据运算关系动态生成要呈现到客户端的JavaScript, 再最终由自定义控件呈现.
(二). 使用步骤
1. 拖三个TextBox控件到页面上, 如图:
2. 设置TextBox1的ID属性为: price; TextBox2的ID属性为: num; TextBox3的ID属性为: sum.
3. 再添加一个AutoCompute控件(本文章主讲控件), 并设置其: Expression 属性值为:
price * num = sum, 意思是: [单价] * [数量] = [总额]
4. 运行即可. 运行后当输入[单价]和[数量]时, 程式能够自动计算[总额]的值.
测试: 当鼠标从[单价]或[数量]控件失去焦点时, 总额值能够重新被计算显示.
5. 扩展:
a. 您也可以输入更复杂的表达式, 比如从上面DropDownList(测试用的控件)里面随便选几个.
b. 不仅能够计算三个TextBox的表达式(如上), 您还可以添加N个TextBox表达式.
功能比较强大吧 :) :)
(三). 表达式规则:
支持JavaScript运算规则, 并支持Math对象的所有属性和方法.
(四). 核心代码
1. Node类文件Node.cs, 用于编译算法中存储数据结点和字符结点
1/**////<summary></summary>
2///Author:[ChengKing(ZhengJian)]
3///Blog:Http://blog.csdn.net/ChengKing
4///
5///<summary></summary>
6///Node的摘要说明
7///
8///<summary></summary>
9///结点类[操作符结点]
10///11publicclassNode
12{
13publicstringstr;//存储本节点字串
14publicintstartIndex;//用于存储一个结点所在[运算表达式]的开始索引位置
15publicintendIndex;//用于存储一个结点所在[运算表达式]的结束索引位置
16
17
18publicNode(intstartIndex,intendIndex,stringstr)
19{
20this.str=str;
21this.startIndex=startIndex;
22this.endIndex=endIndex;
23}
24}
2. 主要控件类 AutoCompute.cs 代码
1///<summary></summary>
2///Author:[ChengKing(ZhengJian)]
3///Blog:Http://blog.csdn.net/ChengKing
4///
5[DefaultProperty("Text")]
6[ToolboxData("{0}:AutoCompute>")]
7publicclassAutoCompute:Control
8{
9[Bindable(true)]
10//[Category("外观")]
11[DefaultValue("[AutoCompute\"AutoCompute1\"]")]
12[Localizable(true)]
13publicstringText
14{
15get
16{
17Strings=(String)ViewState["Text"];
18return((s==null)?String.Empty:s);
19}
20
21set
22{
23ViewState["Text"]=value;
24}
25}
26
27[Bindable(true)]
28[DefaultValue("")]
29[Localizable(true)]
30publicstringExpression
31{
32get
33{
34strings=(string)this.ViewState["Expression"];
35return((s==null)?String.Empty:s);
36}
37set
38{
39this.ViewState["Expression"]=value;
40}
41}
42
43protectedoverridevoidRender(HtmlTextWriterwriter)
44{
45if(DesignMode)
46{
47this.Controls.Clear();
48LiteralControllc=newLiteralControl();
49lc.Text=this.Text;
50this.Controls.Add(lc);
51}
52base.Render(writer);
53}
54
55protectedoverridevoidOnPreRender(EventArgse)
56{
57base.OnPreRender(e);
58
59ConvertHelper_ConvertHelper=newConvertHelper();
60stringstrClientScript;
61try
62{
63if(this.Expression.Trim().Length!=0)
64{
65_ConvertHelper.Main(Page,this.Expression);
66_ConvertHelper.RegisterClientScript(this.Page);
67}
68else
69{
70strClientScript="alert('NoSet[Expression]Property!');";
71if(!Page.ClientScript.IsStartupScriptRegistered("Default_Property"))
72{
73Page.ClientScript.RegisterStartupScript(this.GetType(),"Default_Property",strClientScript,true);
74}
75}
76}
77catch
78{
79strClientScript="alert('The[Expression]formatisnotcorrect!');";
80if(!Page.ClientScript.IsStartupScriptRegistered("Default_Property"))
81{
82Page.ClientScript.RegisterStartupScript(this.GetType(),"Default_Property",strClientScript,true);
83}
84}
85
86}
87
88}
3. ConvertHelper.cs类文件, 主要实现编译算法以及JavaScript脚本生成注册功能.
1///<summary></summary>
2///Author:[ChengKing(ZhengJian)]
3///Blog:Http://blog.csdn.net/ChengKing
4///
5///<summary></summary>
6///ConvertHelper的摘要说明
7///
8///<summary></summary>
9///算法概述:
10///引用概念:[数据变量结点]:用户命名的字串,如:total=price*num,则"price"字串就为数据变量结点
11///1.抽取出操作运算符.并记住所有运算符的索引
12///2.两个操作符之间的字符串为[数据变量结点(用户命名的字串)],但下面几种情况要排除:
13///a.提取的相邻字符中,右边字符为"("操作符时,中间不是数据变量结点.
14///b.两个操作符相邻时,其中间没有字符串,显然也就没有数据变量结点.
15///c.数据变量结点必须是字符串变量,不能为数值.
16///d.排除Math.E等常量情况(Math.E/Math.LN10/Math.LN2/Math.LOG10E/Math.LOG2E/Math.PI/Math.SQRT1_2/Math.SQRT2).
17///
18publicclassConvertHelper
19{
20///<summary></summary>
21///存放JavaScript运算符的各种结点
22///
23privatestring[]OP_Chars=newstring[7]{"+","-","*","/","(",")",","};
24
25///<summary></summary>
26///自定义变量前缀符号
27///
28privatestringVarPreSymbol="_";
29
30///<summary></summary>
31///存储要读取控件的属性(如:t.text/t.Valueetc)
32///
33privatestringValueSymbol=".value";
34
35///<summary></summary>
36///存储compute方法脚本变量
37///
38privatestringComputeScript="";
39
40///<summary></summary>
41///存储onblur方法脚本变量
42///
43privatestringOnblurScript="";
44
45///<summary></summary>
46///区别于方法名的序列号[依次递增,如:compute1,compute2,compute3]
47///
48privateintSequenceNum=1;
49
50///<summary></summary>
51///抽取出运算符结点[其中包括运算符结点的位置信息]
52///
53///
54///<returns></returns>
55privateListNode>BuildOPNode(stringstrObject)
56{
57intbeginIndex=0;//记录当前处理结点的起始索引
58ListNode>nodes=newListNode>();
59
60
61while(true)
62{
63if(beginIndex==strObject.Length)
64{
65break;
66}
67
68for(intj=0;jOP_Chars.Length;j++)
69{
70if(strObject.Length-beginIndex>=OP_Chars[j].Length)
71{
72if(OP_Chars[j]==strObject.Substring(beginIndex,OP_Chars[j].Length))
73{
74//操作符
75Nodenode=newNode(beginIndex,beginIndex+OP_Chars[j].Length-1,strObject.Substring(beginIndex,OP_Chars[j].Length));
76nodes.Add(node);
77break;
78}
79}
80}
81beginIndex++;
82}
83returnnodes;
84}
85
86///<summary></summary>
87///根据运算符结点抽取出数据结点[其中包括数据结点的位置信息]
88///
89///
90///<returns></returns>
91publicListNode>BuildDataNode(stringstrObject)
92{
93strObject=ClearSpace(strObject);
94ListNode>dataNodes=newListNode>();
95ListNode>opNodes=this.BuildOPNode(strObject);
96
97//考虑表达式最左边是数据结点情况,如:A+B表达式中的A
98if(opNodes.Count>0&&opNodes[0].startIndex!=0&&opNodes[0].str!="(")
99{
100stringstr=strObject.Substring(0,opNodes[0].startIndex);
101if(this.JudgeFigure(str)==false&&this.IsIndexOfMath(str)==false)
102{
color: #008080
分享到:
相关推荐
Asp.net 2.0 自定义控件开发简单实现代码
ASP.NET2.0自定义控件和组件开发
Asp.net 2.0 自定义控件开发[浮动工具条控件].rar
Asp.net 2.0 自定义控件开发[开发一个图表(WebChart)控件(柱状图示例)](示例代码下载)收藏
ASP.NET 2.0动态网站开发基础教程(C#) 第05章 ASP.NET2.0服务器控件 内部 新增 增强 验证(共28页).ppt ASP.NET 2.0动态网站开发基础教程(C#) 第06章 ASP.NET数据库编程 ADO ODBC DataSet OLE XML(共27页)....
模仿淘宝的asp.net2.0 分页控件, 内符dll和说明.
ASP.NET 2.0 服务器控件与组件开发 (英文版PDF) Professional ASP.NET 2.0 Server Control and Component Development
ASP.NET 2.0动态网站开发基础教程(C#) 第05章 ASP.NET2.0服务器控件 内部 新增 增强 验证(共28页).ppt ASP.NET 2.0动态网站开发基础教程(C#) 第06章 ASP.NET数据库编程 ADO ODBC DataSet OLE XML(共27页)....
Asp.net 2.0 FileUpload 控件的用法
在开发WEB的时候,尽管IDE提供了很丰富的控件库,但是,很多不能满足我们的需求。ASP.NET2.0服务器控件与组件开发高级编程源代码详细介绍.NET2.0中关于控件的开发过程。
ASP.NET2.0服务器控件开发之实现事件
ASP.NET 2.0动态网站开发基础教程(C#) 第05章 ASP.NET2.0服务器控件 内部 新增 增强 验证(共28页).ppt ASP.NET 2.0动态网站开发基础教程(C#) 第06章 ASP.NET数据库编程 ADO ODBC DataSet OLE XML(共27页)....
ASP.NET 2.0动态网站开发基础教程(C#) 第05章 ASP.NET2.0服务器控件 内部 新增 增强 验证(共28页).ppt ASP.NET 2.0动态网站开发基础教程(C#) 第06章 ASP.NET数据库编程 ADO ODBC DataSet OLE XML(共27页)....
ASP.NET 2.0动态网站开发基础教程(C#) 第05章 ASP.NET2.0服务器控件 内部 新增 增强 验证(共28页).ppt ASP.NET 2.0动态网站开发基础教程(C#) 第06章 ASP.NET数据库编程 ADO ODBC DataSet OLE XML(共27页)....
asp.net 2.0动态网站开发教程
asp.net 2.0 网站开发全程解析 第2版
本书通过深入剖析12个使用ASP.NET 2.0开发的项目,全面阐述了ASP.NET 2.0应用程序的架构及ASP.NET 2.0新增的控件和功能。通过探索这些项目的设计和代码,读者可快速掌握使用ASP.NET 2.0开发应用程序的技巧,从空白...
ASP.NET 2.0快速入门(3):ASP.NET 2.0的新控件
《ASP.NET 2.0 入门经典》将逐步引导您使用 ASP.NET 2.0 创建...5.理解创建 ASP.NET 2.0页面(ASPX)将要使用的工具--Visual Web Developer Express(VWD)太平洋下载中心为您提供"ASP.NET 2.0 入门经典(第4版)"官方下载。