ASP.NET NumberBox Control
By Fons Sonnemans
Number:
Download
NumberBoxDemo.zip
The NumberBox control is an ASP.NET control, which lets the user only input numerical
values. The base class of NumberBox class is the TextBox class. It uses JavaScript
to validate the KeyPress event. An extra RegularExpresionValidator can be used to
validate the control.
Special public properties:
- AllowNegatives
- DecimalPlaces
- DecimalSymbol
- Text
- Value
- ValidationRegularExpression
Demo
Number:
Sample Project
NumberBox Class
using System;
using System.Web.UI;
using System.ComponentModel;
using System.Web.UI.WebControls;
using System.Text;
using System.Text.RegularExpressions;
namespace NumberBoxDemo
{
[
ToolboxData("<{0}:NumberBox
runat=server></{0}:NumberBox>"),
DefaultProperty("DecimalPlaces")
]
public class
NumberBox : TextBox
{
private
int mDecimalPlaces
= 0;
private
char mDecimalSymbol
= '.';
private
bool mAllowNegatives
= true;
[
Bindable(true),
Category("Appearance"),
DefaultValue(0),
Description("Indicates the number of decimal places to display.")
]
public
virtual int DecimalPlaces
{
get
{ return
mDecimalPlaces; }
set
{ mDecimalPlaces
= value;
}
}
[
Bindable(true),
Category("Appearance"),
DefaultValue("."),
Description("The digit grouping symbol.")
]
public
virtual char DecimalSymbol
{
get
{ return
mDecimalSymbol; }
set
{ mDecimalSymbol
= value;
}
}
[
Bindable(true),
Category("Appearance"),
DefaultValue(true),
Description("True when negative values are allowed")
]
public
virtual bool AllowNegatives
{
get
{ return
mAllowNegatives; }
set
{ mAllowNegatives
= value;
}
}
public
virtual double Value
{
get
{
try
{
return ParseStringToDouble(this.Text);
}
catch (FormatException
e)
{
throw new
InvalidOperationException("NumberBox does nog contain a valid
Number.");
}
catch (Exception e)
{
throw e;
}
}
set
{
if ((value < 0)
& !AllowNegatives)
throw new
ArgumentOutOfRangeException("
Only
positive values
are allowed for this NumberBox");
base.Text
= value.ToString(GetFormat()).Replace(".",
DecimalSymbol.ToString());
}
}
override
public string Text
{
get
{
return base.Text;
}
set
{
try {
this.Value
= ParseStringToDouble(value);
} catch
(FormatException e)
{
base.Text
= value;
}
catch (Exception e)
{
throw e;
}
}
}
override
protected void OnPreRender(EventArgs e)
{
if
(this.Page.Request.Browser.JavaScript ==
true)
{
StringBuilder
s = new StringBuilder();
s.Append("\n<script
type='text/javascript' language='JavaScript'>\n");
s.Append("<!--\n");
s.Append(" function
NumberBoxKeyPress(event, dp, dc, n) {\n");
s.Append("
var myString = new String(event.srcElement.value);\n");
s.Append("
var pntPos = myString.indexOf(String.fromCharCode(dc));\n");
s.Append("
var keyChar = window.event.keyCode;\n");
s.Append("
if ((keyChar < 48) || (keyChar > 57)) {\n");
s.Append("
if (keyChar == dc) {\n");
s.Append("
if ((pntPos != -1) || (dp < 1)) {\n");
s.Append("
return false;\n");
s.Append("
}\n");
s.Append("
} else \n");
s.Append("if
(((keyChar == 45) && (!n || myString.length != 0)) || (keyChar != 45)) \n");
s.Append("
return false;\n");
s.Append("
}\n");
s.Append("
return true;\n");
s.Append(" }\n");
s.Append("//
-->\n");
s.Append("</script>\n");
this.Page.RegisterClientScriptBlock("NumberBoxKeyPress", s.ToString());
try {
this.Attributes.Remove("onKeyPress");
} finally
{
this.Attributes.Add("onKeyPress",
"return NumberBoxKeyPress(event, "
+ DecimalPlaces.ToString()
+ ", "
+ ((int)DecimalSymbol).ToString()
+ ", "
+ AllowNegatives.ToString().ToLower()
+ ")");
}
}
}
virtual
public string ValidationRegularExpression
{
get
{
StringBuilder
regexp =
new StringBuilder();
if (AllowNegatives)
regexp.Append("([-]|[0-9])");
regexp.Append("[0-9]*");
if (DecimalPlaces >
0)
{
regexp.Append("([");
regexp.Append(DecimalSymbol);
regexp.Append("]|[0-9]){0,1}[0-9]{0,");
regexp.Append(DecimalPlaces.ToString());
regexp.Append("}$");
}
return regexp.ToString();
}
}
virtual
protected double ParseStringToDouble(string s)
{
s
= s.Replace(DecimalSymbol.ToString(), ".");
return
double.Parse(s);
}
virtual
protected string GetFormat()
{
StringBuilder
f = new StringBuilder();
f.Append("0");
if
(DecimalPlaces > 0)
{
f.Append(".");
f.Append('0', DecimalPlaces);
}
return
f.ToString();
}
}
}
Validation
You can use a normal RegularExpressionValidator control to validate the NumberBox.
Invalid nummers are then rejected without causing a roundtrip to the server. Invalid
numbers can still be entered using the clipboard Paste option. I don't know how
to avoid this.
You can use the NumberBox.ValidationRegularExpression property to set the RegularExpressionValidator.ValidationRegularExpression
property to the correct RegularExpression.
private void
Page_Load(object
sender,
System.EventArgs e)
{
if
(!IsPostBack)
{
valOne.ValidationExpression
= numOne.ValidationRegularExpression;
valTwo.ValidationExpression
= numTwo.ValidationRegularExpression;
}
}
WebForm1.aspx
<%@ Page language="c#" Codebehind="WebForm1.aspx.cs" AutoEventWireup="false"
Inherits="NumberBoxDemo.WebForm1"
%>
<%@ Register TagPrefix="rit" Namespace="NumberBoxDemo"
Assembly="NumberBoxDemo"
%>
<!DOCTYPE HTML PUBLIC "-//W3C//DTD
HTML 4.0 Transitional//EN" >
<HTML>
<HEAD>
<meta
content="Microsoft
Visual Studio 7.0" name="GENERATOR">
<meta
content="C#"
name="CODE_LANGUAGE">
<meta
content="JavaScript
(ECMAScript)" name="vs_defaultClientScript">
<meta
content="http://schemas.microsoft.com/intellisense/ie5"
name="vs_targetSchema">
</HEAD>
<body
style="FONT-FAMILY: Verdana">
<form
id="Form1"
method="post"
runat="server">
<H2>
NumberBox
Demo Page
</H2>
<P>
<TABLE
cellSpacing="1" cellPadding="1" width="100%" border="0">
<TR>
<TD
style="WIDTH:
300px">
Numberbox1:
</TD>
<TD>
<rit:numberbox
id="numOne"
runat="server"
DecimalSymbol=","
MaxLength="8" DecimalPlaces="2">
32,46
</rit:numberbox>
</TD>
<TD>
<asp:regularexpressionvalidator
id="valOne"
runat="server"
ControlToValidate="numOne">
Invalid
Number</asp:regularexpressionvalidator>
</TD>
</TR>
<TR>
<TD
style="WIDTH:
300px" vAlign="top">
<FONT
size="1">(Double,
2 decimals,
',' DecimalSymbol)</FONT>
</TD>
<TD>
</TD>
<TD>
</TD>
</TR>
<TR>
<TD
style="WIDTH:
300px">
</TD>
<TD>
</TD>
<TD>
</TD>
</TR>
<TR>
<TD
style="WIDTH:
300px">
Numberbox2:
</TD>
<TD>
<rit:numberbox
id="numTwo"
runat="server"
MaxLength="8"
DecimalSymbol="." AllowNegatives="False">
</rit:numberbox>
</TD>
<TD>
<asp:RegularExpressionValidator
id="valTwo"
runat="server"
ControlToValidate="numTwo">
Invalid
Number</asp:RegularExpressionValidator>
</TD>
</TR>
<TR>
<TD
style="WIDTH:
300px" vAlign="top">
<FONT
size="1">(Poisitive Integer)</FONT>
</TD>
<TD>
</TD>
<TD>
</TD>
</TR>
<TR>
<TD
style="WIDTH:
300px">
</TD>
<TD>
</TD>
<TD>
</TD>
</TR>
</TABLE>
</P>
<P>
</P>
<P>
<asp:button
id="btnSubmit"
runat="server"
Text="Submit"></asp:button>
</P>
<P>
<asp:PlaceHolder id="PlaceHolder1"
runat="server"></asp:PlaceHolder>
</P>
<P>
</P>
</form>
</body>
</HTML>
WebForm1.aspx.cs
using System;
using System.Collections;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Web;
using System.Web.SessionState;
using System.Web.UI;
using System.Web.UI.WebControls;
using System.Web.UI.HtmlControls;
namespace NumberBoxDemo
{
public
class WebForm1 :
System.Web.UI.Page
{
protected
NumberBoxDemo.NumberBox numOne;
protected
System.Web.UI.WebControls.RegularExpressionValidator
valOne;
protected
NumberBoxDemo.NumberBox numTwo;
protected
System.Web.UI.WebControls.RegularExpressionValidator
valTwo;
protected
System.Web.UI.WebControls.PlaceHolder
PlaceHolder1;
protected
System.Web.UI.WebControls.Button
btnSubmit;
public
WebForm1()
{
Page.Init +=
new System.EventHandler(Page_Init);
}
private
void Page_Load(object sender,
System.EventArgs e)
{
if
(!IsPostBack)
{
valOne.ValidationExpression
= numOne.ValidationRegularExpression;
valTwo.ValidationExpression
= numTwo.ValidationRegularExpression;
}
}
private
void Page_Init(object sender,
EventArgs e)
{
InitializeComponent();
}
#region Web
Form Designer generated code
private
void InitializeComponent()
{
this.btnSubmit.Click
+=
new System.EventHandler(this.btnSubmit_Click);
this.Load +=
new System.EventHandler(this.Page_Load);
}
#endregion
private
void btnSubmit_Click(object
sender, System.EventArgs
e)
{
numTwo.Value =
new Random().NextDouble()
* 1000;
this.PlaceHolder1.Controls.Clear();
this.PlaceHolder1.Controls.Add(new
LiteralControl(
"Numberbox1.Value = "
+ numOne.Value.ToString()
+ "<br>"));
this.PlaceHolder1.Controls.Add(new
LiteralControl(
"Numberbox1.Text = "
+ numOne.Text
+ "<br>"));
this.PlaceHolder1.Controls.Add(new
LiteralControl(
"Numberbox1.ValidationRegularExpression = "
+ numOne.ValidationRegularExpression
+ "<br>"));
}
}
}
Any suggestions and feedback for improving this article is most welcome. Send your
suggestions and feedback to Fons.Sonnemans@reflectionit.nl