创建数字文本框控件

分享于 

13分钟阅读

Web开发

  繁體

数字文本框

介绍

在本文中,我们将学习如何逐步创建只接受数字字符的自定义textbox控件。 控件允许客户端代码指定它是否应作为整数或者十进制文本框工作。

这里自定义控件将使用 Visual Studio 2008实现。 但是,同样的代码可以使用以前版本的Visual Studio 编写。 我将要使用的编程语言包括: C# 和 JavaScript。

准备项目

首先,让我们准备项目和我们要使用的文件。 请遵循以下简单步骤:

  • 创建一个类库的新项目,并将它的设置为 MyCustomControls。

创建新的ClassLibrary项目

  • 确保你添加了对 System.Web 库的引用。

添加对 System.Web的引用

  • 默认情况下,Visual Studio 将添加一个名为'Class1.cs'的文件。 请 delete 文件,并添加两个具有以下名称的文件: NumericTextBox.cs。 另外,使用 NAME'资源'创建一个新文件夹,并添加一个带有 NAME'NumericTextBox.js'的JavaScript文件。

插入所需文件

  • 为了使JavaScript嵌入组件,我们需要将它的BuildAction 属性更改为'嵌入式资源'。 请参见下面的图:

将javascript文件BuildAction属性更改为嵌入资源

C# 代码

为什么两个 C# 文件?

你可能已经注意到,我们有两个 C# 文件。 它们都将用于实现同一个类: NumericTextBox 但是,关键字 部分 将被添加到定义中以便编译器知道两个类表示最后一个类。 web服务的文件将用于实现控件的逻辑,而 NumericTextBoxExtention.cs 插件将包含所有字段或者属性。

看看下面的代码,看看如何在 NumericTextBox.cs 文件中定义 NumericTextBox 类。 代码 Fragment 2显示了 NumericTextBoxExtention.cs 文件中的代码。

请注意,分部类是添加到. NET 版本 2.0和更高版本的特性。 如果你使用的是 1的.NET 版本,则可以将所有代码放置在一个类中。

//// Code Snippet 1//using System;using System.Web.UI;
[assembly: WebResource("MyCustomControls.Resources.NumericTextBox.js", "text/javascript")]namespace MyCustomControls
{
 [ToolboxData(@"<{0}:NumericTextBox Text="""" runat=""server""></{0}:NumericTextBox>")]
 publicpartialclass NumericTextBox : System.Web.UI.WebControls.TextBox
 {
 }
} //// Code Snippet 2//namespace MyCustomControls
{
 publicpartialclass NumericTextBox : System.Web.UI.WebControls.TextBox
 {
 }
}
字段和属性

代码 Fragment 1中添加了一些属性。 现在不用担心它们了,我们将在本文后面讨论它们。 现在我们想看看在 NumericTextBoxExtention.cs 文件中需要实现哪些属性。

让我们考虑一些我们可能需要的属性。 首先,我们曾经说过,我们的控制对于整数和小数都是有效的。 因此,添加名为 Type的属性是明智的。 这里属性的类型可以为 int 或者 字符串 但是,我认为最好是添加一个 enum 命名为 TextBoxType,并让我们的属性类型为这个 enum。

此外,我们还需要一个属性来指定允许的整数数。 在小数文本框中,我们还需要一个属性来指定小数点后允许的最大分数数。 我们将添加一个属性来指定这个控件是否应该接受负值。 请查看代码 Fragment 3,看看它是如何实现的。

//// Code Snippet 3//publicenum TextBoxType
{
 Integer,
 Decimal
}privateint _NumberOfFraction = 0;privateint _NumberOfInteger = 0;privatebool _AllowNegative = false;private TextBoxType _Type = TextBoxType.Integer;publicint NumberOfFraction
{
 get { return _NumberOfFraction; }
 set { _NumberOfFraction = value; }
}publicint NumberOfInteger
{
 get { return _NumberOfInteger; }
 set { _NumberOfInteger = value; }
}publicbool AllowNegative
{
 get { return _AllowNegative; }
 set { _AllowNegative = value; }
}public TextBoxType Type
{
 get { return _Type; }
 set { _Type = value; }
}
属性

在编译时需要将一个属性添加到命名空间中,以便让编译器知道这里有一个资源,就像你在代码 Fragment 1中看到的。 我们已经在 Pattern 中指定了JavaScript文件的路径: "项目 Name.Folder Name.File 名称"。

在 Visual Studio 中,将任何 ASP.NET 控件拖放到页面中。 它将自动创建必要的标签和属性。 为了让控件具有相同的行为,我们在类 NAME 中添加了一个属性。 请参考代码 Fragment 1. {0} 将被你在 web.config 或者任何配置文件中指定的值替换。 对于 ASP.NET 控件,默认情况下为 asp

请参阅代码段 4,了解如何在你的web.config 中指定该值。 因此,当将控件拖放到网页上时,它看起来就像代码 Fragment 5.

<!--//
//Code Snippet 4
//--><pages><controls><addtagPrefix="mcc"namespace="MyCustomControls"assembly="MyCustomControls"/>. 
. 
. <--////CodeSnippet5//--><mcc:NumericTextBoxText=""runat="server"></mcc:NumericTextBox>
重写 OnPreRender

要实现控件的初始呈现,我们需要重写 OnPreRender 以实现该方法。 换句话说,我们希望 OnPreRender 方法知道我们希望控件不仅仅是正常的textbox。

基本上我们将在 OnPreRender 方法中做两件事。 首先添加代码,让该方法添加对我们的JavaScript文件的引用。 第二,在某些事件中添加对JavaScript函数的调用。 请参考代码 Fragment 6.

//// Code Snippet 6//protectedoverridevoid OnPreRender(EventArgs e)
{
 base.OnPreRender(e);
 ClientScriptManager scriptManager = this.Page.ClientScript;
 string resourceFilePath = "MyCustomControls.Resources.NumericTextBox.js";
 // This will register a Javascript block witht the name 'NumericTextBoxScript' scriptManager.RegisterClientScriptInclude("NumericTextBoxScript", 
 scriptManager.GetWebResourceUrl(this.GetType(), resourceFilePath));
 if (this.Type == TextBoxType.Decimal)
 this.Attributes.Add("onkeydown", 
 string.Format("return CheckDecimal(this,'{0}','{1}', {2})", 
 NumberOfInteger, NumberOfFraction, _AllowNegative.ToString().ToLower()));
 elseif (this.Type == TextBoxType.Integer)
 this.Attributes.Add("onkeydown", string.Format("return CheckInteger({0})", 
 _AllowNegative.ToString().ToLower()));
 this.Attributes.Add("onkeyup", string.Format("return CheckNegative(this)", 
 _AllowNegative.ToString().ToLower()));
}

JavaScript代码

我们将有三个JavaScript函数。 如果控件作为整数文本框,则将在 keydown 事件上调用第一个 CheckInteger。 第二个 CheckDecimal,当控件作为十进制文本框工作时,将在 keydown 事件中调用。 finally,第三个函数 CheckNegative 将在 keyup 事件上调用,无论控件如何工作。

CheckInteger 将简单检查按下的字符的ASCII代码是否在允许的List 内。 它还将确保文本框中不存在一个上的破折号( - )。

在将这里函数设置为textbox事件之前,调用该函数的原因不是 keyup,因此我有机会终止该操作。 因此,如果函数返回 falsekeydown 事件中,不会将字符添加到文本框中。

另一方面,如果函数返回 falsekeyup 事件中,什么都不会改变。 但是,keyup 事件的好处是它允许我读取文本框的值,因为它在值被设置后引发。

//// Code Snippet 7//function CheckInteger(allowNegative) {
 if ((event.keyCode> = 48 && event.keyCode <= 57 && event.shiftKey == false) ||
 // 0-9 numbers  (event.keyCode> = 96 && event.keyCode <= 105 && event.shiftKey == false) ||
 // 0-9 numbers (the numeric keys at the right of the keyboard) (event.keyCode> = 37 && event.keyCode <= 40) || // Left, Up, Right and Down  event.keyCode == 8 || // backspaceASKII event.keyCode == 9 || // tabASKII event.keyCode == 16 || // shift event.keyCode == 17 || // control event.keyCode == 35 || // End event.keyCode == 36 || // Home event.keyCode == 46) // deleteASKIIreturntrue;
 elseif (event.keyCode == 189 && allowNegative == true) { // dash (-)if (sender.value.indexOf('-', 0)> -1)
 returnfalse;
 elsereturntrue;
 }
 elsereturnfalse;
}

CheckDecimalCheckInteger 非常相似。 但在某些情况下它们是不同的。 CheckDecimal 将以不同的方式处理数字字符,而不是其他允许的键。 这是因为当一个数字被按下时,我们需要检查整数和分数的数目是否仍在极限范围内。

此外,它还对小数点字符进行特殊处理。 它不应该是文本框中的第一个字符,而且它不应该出现多次。

//// Code Snippet 8//function CheckDecimal(sender, numberOfInteger, numberOfFrac, allowNegative) {
 var valueArr;
 if ((event.keyCode> = 37 && event.keyCode <= 40) || // Left, Up, Right and Down event.keyCode == 8 || // backspaceASKII event.keyCode == 9 || // tabASKII event.keyCode == 16 || // shift event.keyCode == 17 || // control event.keyCode == 35 || // End event.keyCode == 36 || // Home event.keyCode == 46) // deleteASKIIreturntrue;
 elseif (event.keyCode == 189 && allowNegative == true) { // dash (-)if (sender.value.indexOf('-', 0)> -1)
 returnfalse;
 elsereturntrue;
 }
 valueArr = sender.value.split('.');
 if (event.keyCode == 190) { // decimal point (.)if (valueArr[0]!= null && valueArr[1] == null)
 returntrue;
 elsereturnfalse;
 }
 if ((event.keyCode> = 48 && event.keyCode <= 57 && event.shiftKey == false) ||
 // 0-9 numbers  (event.keyCode> = 96 && event.keyCode <= 105 && event.shiftKey == false)) {
 // 0-9 numbers (the numeric keys at the right of the keyboard)if (valueArr[1] == null) {
 if (valueArr[0].indexOf('-', 0)> -1)
 numberOfInteger++;
 if (valueArr[0].length <= numberOfInteger)
 returntrue;
 }
 else {
 if (valueArr[1].length <= numberOfFrac)
 returntrue;
 }
 }
 returnfalse;
}

当键启动时,CheckNegative 函数将确保将字符串/减号字符添加到左侧。

//// Code Snippet 9//function CheckNegative(sender) {
 if (event.keyCode == 189) { // dash (-)if (sender.value.indexOf('-', 0)> 0)
 sender.value = sender.value.replace('-', '');
 }
}

相关文章