C#中只接受数字输入的控件
关键字: numeric textbox
在MFC里需要获取文本输入时,经常会用到
CEdit或者它的子类。可以通过设置它的
Edit Control Styles来控制Edit控件的一些行为,例如说设置
ES_NUMBER标识使控件只允许接受数字(虽然可以复制-粘贴非数字字符串到这个控件中)。
在.NET中,用于获取文本输入的控件是 TextBox,但TextBox本身并不包含可以直接调用的方法或属性来将其设置为只接受数字输入。这个问题有好几种方法来解决:
光是 CodeProject上就有好几个与这个相关的实现:
Validating Edit Controls。包括了NumericTextBox、AlphanumericTextBox、DateTextBox等许多版本的TextBox子类。值得一看。
A numeric textbox with a twist。
Numeric TextBox : Allow your users to enter numeric data the easy way。 使用MaskedTextBox控件; 这是.NET Framework自带的一个TextBox的子类,实现了一个带过滤功能的TextBox,可以自定义接受的输入内容的格式。只要设置其 stringMask属性即可。如果觉得 ES_NUMBER的功能不够用,而自行监听KeyDown事件来做验证不够优雅的话,这个MaskedTextBox绝对是值得考虑的选择。例如说,要接受0到999999的数字,只要把Mask属性设为 "999,999.00"就行(意味着六位的可选十进制数字,一个小数点,和两位必须输入的小数)。 MSDN上对这个控件有个简单的 walkthrough。 使用NumericUpDown控件。 当需要获取简单数字输入时,在.NET世界中最直接的方法不是去想办法与TextBox搏斗,而应该换个控件来用——NumericUpDown。这个控件不但能接受来自键盘的数字输入,还有一组上下箭头来步进。它包含了许多可以设置的属性,例如显示分隔符逗号的 boolThousandsSeparator、控制最小/最大值的 decimalMinimum/ decimalMaximum属性等。
下面对这几种解决方法的其中一些稍微讨论一下。
=========================================================================================
一、继承TextBox并覆盖其CreateParams属性
使用这种方法的NumericTextBox的实现(代码的第1-12行)及用例:
运行程序,在输入任意非0-9的字符时的样子:
(截图反映的是在我的简体中文Windows XP上的运行效果;若系统语言不是简体中文的话会根据系统语言而不同)
如果这个文本框已经能满足需求,就没必要自己监听KeyDown事件那么麻烦了。
=========================================================================================
二、自行监听KeyDown事件
可以参考CodeProject上 Numeric TextBox : Allow your users to enter numeric data the easy way的实现方式。基本原理就是在KeyDown的响应方法中对e.KeyCode进行判断,如果输入不满足条件则设置某个标识,然后再KeyPress的响应方法里设置e.Handled = true;来取消该次事件。
最简单来说类似这样:
(判断逻辑来自 KeyEventArgs在MSDN文档上的 范例代码)
得到的文本框外观与一般的TextBox没区别,只是无法由键盘输入数字字符以外的字符。要避免任意字符串被复制-粘贴进来的话,要另外做些判断。这里就不详细写了。
=========================================================================================
三、使用MaskedTextBox
使用例子:
这段代码是手写的;要是用VS2005/VS2008的设计器的话,这个例子的所有功能都能直接在设计器里指定。
输入内容(可以看到分隔符都不需要自己写了,已经写好在输入框里;只要填空就行):
输入内容不符合Mask属性指定的模式时:
=========================================================================================
四、使用NumericUpDown
这段代码是手写的;要是用VS2005/VS2008的设计器的话,这个例子的所有功能都能直接在设计器里指定。
NumericUpDown的内容的值可以用Value属性来设置或获取,类型为 decimal。
截图:(输入不符合要求的字符时,默认行为是beep一下,没有工具条的提示)
在.NET中,用于获取文本输入的控件是 TextBox,但TextBox本身并不包含可以直接调用的方法或属性来将其设置为只接受数字输入。这个问题有好几种方法来解决:
- 继承TextBox并覆盖其CreateParams属性,对该属性的Style成员添加ES_NUMBER标识; 这个方法与MFC中用Edit Control Styles来初始化CEdit一样。可以说是最偷懒的方法。
- 自行监听TextBox的KeyDown事件,实现输入验证(但不保证复制-粘贴输入的正确性); 其实设置
光是 CodeProject上就有好几个与这个相关的实现:
Validating Edit Controls。包括了NumericTextBox、AlphanumericTextBox、DateTextBox等许多版本的TextBox子类。值得一看。
A numeric textbox with a twist。
Numeric TextBox : Allow your users to enter numeric data the easy way。 使用MaskedTextBox控件; 这是.NET Framework自带的一个TextBox的子类,实现了一个带过滤功能的TextBox,可以自定义接受的输入内容的格式。只要设置其 stringMask属性即可。如果觉得 ES_NUMBER的功能不够用,而自行监听KeyDown事件来做验证不够优雅的话,这个MaskedTextBox绝对是值得考虑的选择。例如说,要接受0到999999的数字,只要把Mask属性设为 "999,999.00"就行(意味着六位的可选十进制数字,一个小数点,和两位必须输入的小数)。 MSDN上对这个控件有个简单的 walkthrough。 使用NumericUpDown控件。 当需要获取简单数字输入时,在.NET世界中最直接的方法不是去想办法与TextBox搏斗,而应该换个控件来用——NumericUpDown。这个控件不但能接受来自键盘的数字输入,还有一组上下箭头来步进。它包含了许多可以设置的属性,例如显示分隔符逗号的 boolThousandsSeparator、控制最小/最大值的 decimalMinimum/ decimalMaximum属性等。
下面对这几种解决方法的其中一些稍微讨论一下。
=========================================================================================
一、继承TextBox并覆盖其CreateParams属性
使用这种方法的NumericTextBox的实现(代码的第1-12行)及用例:
- publicclassNumericTextBox:System.Windows.Forms.TextBox
- {
- privateconstintES_NUMBER=0x2000;//(definedinWinUser.h)
- protectedoverrideSystem.Windows.Forms.CreateParamsCreateParams{
- get{
- System.Windows.Forms.CreateParamscp=base.CreateParams;
- cp.Style|=ES_NUMBER;
- returncp;
- }
- }
- }
- #regionusecasecodesample
- sealedclassTestForm:System.Windows.Forms.Form
- {
- privateNumericTextBoxm_ntxt;
- publicTestForm(){
- InitializeComponent();
- }
- privatevoidInitializeComponent(){
- this.m_ntxt=newNumericTextBox();
- this.m_ntxt.Dock=System.Windows.Forms.DockStyle.Fill;
- this.ClientSize=newSystem.Drawing.Size(100,60);
- this.Controls.Add(this.m_ntxt);
- this.PerformLayout();
- }
- [System.STAThread]
- staticvoidMain(string[]args){
- System.Windows.Forms.Application.EnableVisualStyles();
- System.Windows.Forms.Application.SetCompatibleTextRenderingDefault(false);
- System.Windows.Forms.Application.Run(newTestForm());
- }
- }
- #endregion
运行程序,在输入任意非0-9的字符时的样子:
![](https://i-blog.csdnimg.cn/blog_migrate/92b63cb9acb89b5919c8532a39005c2b.jpeg)
(截图反映的是在我的简体中文Windows XP上的运行效果;若系统语言不是简体中文的话会根据系统语言而不同)
如果这个文本框已经能满足需求,就没必要自己监听KeyDown事件那么麻烦了。
=========================================================================================
二、自行监听KeyDown事件
可以参考CodeProject上 Numeric TextBox : Allow your users to enter numeric data the easy way的实现方式。基本原理就是在KeyDown的响应方法中对e.KeyCode进行判断,如果输入不满足条件则设置某个标识,然后再KeyPress的响应方法里设置e.Handled = true;来取消该次事件。
最简单来说类似这样:
- usingSystem;
- usingSystem.Drawing;
- usingSystem.Windows.Forms;
- sealedclassTestForm:Form
- {
- privateTextBoxm_textBox;
- privateboolm_nonNumberEntered=false;
- publicTestForm(){
- InitializeComponent();
- }
- privatevoidInitializeComponent(){
- this.m_textBox=newTextBox();
- this.m_textBox.Dock=DockStyle.Fill;
- this.m_textBox.KeyDown+=m_textBox_KeyDown;
- this.m_textBox.KeyPress+=m_textBox_KeyPress;
- this.ClientSize=newSize(100,60);
- this.Controls.Add(this.m_textBox);
- this.PerformLayout();
- }
- privatevoidm_textBox_KeyDown(objectsender,KeyEventArgse){
- //Initializetheflagtofalse.
- m_nonNumberEntered=false;
- //Determinewhetherthekeystrokeisanumberfromthetopofthekeyboard.
- if(e.KeyCode<Keys.D0||e.KeyCode>Keys.D9){
- //Determinewhetherthekeystrokeisanumberfromthekeypad.
- if(e.KeyCode<Keys.NumPad0||e.KeyCode>Keys.NumPad9){
- //Determinewhetherthekeystrokeisabackspace.
- if(e.KeyCode!=Keys.Back){
- //Anon-numericalkeystrokewaspressed.
- //SettheflagtotrueandevaluateinKeyPressevent.
- m_nonNumberEntered=true;
- }
- }
- }
- }
- privatevoidm_textBox_KeyPress(objectsender,KeyPressEventArgse){
- //CheckfortheflagbeingsetintheKeyDownevent.
- if(m_nonNumberEntered){
- //Stopthecharacterfrombeingenteredintothecontrol
- //sinceitisnon-numerical.
- e.Handled=true;
- }
- }
- [STAThread]
- staticvoidMain(string[]args){
- Application.EnableVisualStyles();
- Application.SetCompatibleTextRenderingDefault(false);
- Application.Run(newTestForm());
- }
- }
(判断逻辑来自 KeyEventArgs在MSDN文档上的 范例代码)
得到的文本框外观与一般的TextBox没区别,只是无法由键盘输入数字字符以外的字符。要避免任意字符串被复制-粘贴进来的话,要另外做些判断。这里就不详细写了。
=========================================================================================
三、使用MaskedTextBox
使用例子:
- usingSystem;
- usingSystem.Windows.Forms;
- sealedclassTestForm:Form
- {
- privateMaskedTextBoxm_maskedTextBox;
- privateToolTipm_toolTip;
- publicTestForm(){
- InitializeComponent();
- }
- privatevoidInitializeComponent(){
- this.m_maskedTextBox=newMaskedTextBox();
- this.m_maskedTextBox.Mask="999,999.00";
- this.m_maskedTextBox.Dock=DockStyle.Fill;
- this.m_maskedTextBox.MaskInputRejected+=m_maskedTextBox_InputRejected;
- this.m_maskedTextBox.KeyDown+=m_maskedTextBox_KeyDown;
- this.m_toolTip=newToolTip();
- this.ClientSize=newSize(100,60);
- this.Controls.Add(this.m_maskedTextBox);
- this.PerformLayout();
- }
- privatevoidm_maskedTextBox_InputRejected(objectsender,
- MaskInputRejectedEventArgse){
- toolTip.ToolTipTitle="InvalidInput";
- toolTip.Show("Onlydigits(0-9)areallowed.",
- m_maskedTextBox,m_maskedTextBox.Location,5000);
- }
- privatevoidm_maskedTextBox_KeyDown(objectsender,KeyEventArgse){
- m_toolTip.Hide(maskedTextBox);
- }
- [STAThread]
- staticvoidMain(string[]args){
- Application.EnableVisualStyles();
- Application.SetCompatibleTextRenderingDefault(false);
- Application.Run(newTestForm());
- }
- }
这段代码是手写的;要是用VS2005/VS2008的设计器的话,这个例子的所有功能都能直接在设计器里指定。
输入内容(可以看到分隔符都不需要自己写了,已经写好在输入框里;只要填空就行):
![](https://i-blog.csdnimg.cn/blog_migrate/1f5a009271de0de4da186215e6844826.jpeg)
输入内容不符合Mask属性指定的模式时:
![](https://i-blog.csdnimg.cn/blog_migrate/a23bb4ca91699a35301c9825eeb3a5bc.jpeg)
=========================================================================================
四、使用NumericUpDown
- usingSystem;
- usingSystem.Drawing;
- usingSystem.Windows.Forms;
- sealedclassTestForm:Form
- {
- privateNumericUpDownm_numericUpDown;
- publicTestForm(){
- InitializeComponent();
- }
- privatevoidInitializeComponent(){
- this.m_numericUpDown=newNumericUpDown();
- this.m_numericUpDown.Value=100;
- this.m_numericUpDown.Dock=DockStyle.Fill;
- this.m_numericUpDown.ThousandsSeparator=true;
- this.m_numericUpDown.Maximum=int.MaxValue;
- this.ClientSize=newSize(100,60);
- this.Controls.Add(this.m_numericUpDown);
- this.PerformLayout();
- }
- [System.STAThread]
- staticvoidMain(string[]args){
- Application.EnableVisualStyles();
- Application.SetCompatibleTextRenderingDefault(false);
- Application.Run(newTestForm());
- }
- }
这段代码是手写的;要是用VS2005/VS2008的设计器的话,这个例子的所有功能都能直接在设计器里指定。
NumericUpDown的内容的值可以用Value属性来设置或获取,类型为 decimal。
截图:(输入不符合要求的字符时,默认行为是beep一下,没有工具条的提示)
![](https://i-blog.csdnimg.cn/blog_migrate/b0d7e52135cebc59b47fb62ec34bd895.jpeg)