VB.net 2010 视频教程 VB.net 2010 视频教程 python基础视频教程
SQL Server 2008 视频教程 c#入门经典教程 Visual Basic从门到精通视频教程
当前位置:
首页 > temp > C#教程 >
  • c#只接受数字输入的控件

制作者:剑锋冷月 单位:无忧统计网,www.51stat.net
 

  在MFC里需要获取文本输入时,经常会用到CEdit或者它的子类。可以通过设置它的Edit Control Styles来控制Edit控件的一些行为,例如说设置ES_NUMBER标识使控件只允许接受数字(虽然可以复制-粘贴非数字字符串到这个控件中)。

  在.NET中,用于获取文本输入的控件是TextBox,但TextBox本身并不包含可以直接调用的方法或属性来将其设置为只接受数字输入。这个问题有好几种方法来解决:

  继承TextBox并覆盖其CreateParams属性,对该属性的Style成员添加ES_NUMBER标识; 这个方法与MFC中用Edit Control Styles来初始化CEdit一样。可以说是最偷懒的方法。

  自行监听TextBox的KeyDown事件,实现输入验证(但不保证复制-粘贴输入的正确性); 其实设置ES_NUMBER做的也是这件事,如果要实现的功能与Windows控件中默认的一样的话没必要自己监听KeyDown事件;如果需要些额外的功能,例如说允许输入负数、十六进制数等默认没有的功能时,则监听KeyDown事件是个有效的方式。

  使用第三方编写的继承自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,可以自定义接受的输入内容的格式。只要设置其string Mask属性即可。如果觉得ES_NUMBER的功能不够用,而自行监听KeyDown事件来做验证不够优雅的话,这个MaskedTextBox绝对是值得考虑的选择。例如说,要接受0到999999的数字,只要把Mask属性设为"999,999.00"就行(意味着六位的可选十进制数字,一个小数点,和两位必须输入的小数)。MSDN上对这个控件有个简单的walkthrough。

 

  使用NumericUpDown控件。   当需要获取简单数字输入时,在.NET世界中最直接的方法不是去想办法与TextBox搏斗,而应该换个控件来用——NumericUpDown。这个控件不但能接受来自键盘的数字输入,还有一组上下箭头来步进。它包含了许多可以设置的属性,例如显示分隔符逗号的bool ThousandsSeparator、控制最小/最大值的decimal Minimum/decimal Maximum属性等。

  下面对这几种解决方法的其中一些稍微讨论一下。

  一、继承TextBox并覆盖其CreateParams属性

  使用这种方法的NumericTextBox的实现(代码的第1-12行)及用例:

  C#代码   

 

public class NumericTextBox : System.Windows.Forms.TextBox
{
    private const int ES_NUMBER = 0x2000; // ( defined in WinUser.h )
    
    protected override System.Windows.Forms.CreateParams CreateParams {
        get {
            System.Windows.Forms.CreateParams cp = base.CreateParams;            
            cp.Style |= ES_NUMBER;
            return cp;
        }
    }
}

#region use case code sample

sealed class TestForm : System.Windows.Forms.Form
{
    private NumericTextBox m_ntxt;
    
    public TestForm() {
        InitializeComponent();
    }
    
    private void InitializeComponent() {
        this.m_ntxt = new NumericTextBox();
        this.m_ntxt.Dock = System.Windows.Forms.DockStyle.Fill;
        
        this.ClientSize = new System.Drawing.Size(100, 60);
        this.Controls.Add(this.m_ntxt);
        this.PerformLayout();
    }
    
    [System.STAThread]
    static void Main(string[] args) {
        System.Windows.Forms.Application.EnableVisualStyles();
        System.Windows.Forms.Application.SetCompatibleTextRenderingDefault(false);
        System.Windows.Forms.Application.Run(new TestForm());
    }
}

#endregion

 

 

 


 

  运行程序,在输入任意非0-9的字符时的样子:

C#中只接受数字输入的控件

  (截图反映的是在我的简体中文Windows XP上的运行效果;若系统语言不是简体中文的话会根据系统语言而不同)

  如果这个文本框已经能满足需求,就没必要自己监听KeyDown事件那么麻烦了。

  二、自行监听KeyDown事件

  可以参考CodeProject上Numeric TextBox : Allow your users to enter numeric data the easy way的实现方式。基本原理就是在KeyDown的响应方法中对e.KeyCode进行判断,如果输入不满足条件则设置某个标识,然后再KeyPress的响应方法里设置e.Handled = true;来取消该次事件。

  最简单来说类似这样:

  C#代码   

 

using System;
using System.Drawing;
using System.Windows.Forms;

sealed class TestForm : Form
{
    private TextBox m_textBox;
    private bool m_nonNumberEntered = false;
    
    public TestForm() {
        InitializeComponent();
    }
    
    private void InitializeComponent() {
        this.m_textBox = new TextBox();
        this.m_textBox.Dock = DockStyle.Fill;
        this.m_textBox.KeyDown += m_textBox_KeyDown;
        this.m_textBox.KeyPress += m_textBox_KeyPress;
        
        this.ClientSize = new Size(100, 60);
        this.Controls.Add(this.m_textBox);
        this.PerformLayout();
    }
    
    private void m_textBox_KeyDown(object sender, KeyEventArgs e) {
        // Initialize the flag to false.
        m_nonNumberEntered = false;
    
        // Determine whether the keystroke is a number from the top of the keyboard.
        if (e.KeyCode < Keys.D0 || e.KeyCode > Keys.D9) {
            // Determine whether the keystroke is a number from the keypad.
            if (e.KeyCode < Keys.NumPad0 || e.KeyCode > Keys.NumPad9) {
                // Determine whether the keystroke is a backspace.
                if(e.KeyCode != Keys.Back) {
                    // A non-numerical keystroke was pressed.
                    // Set the flag to true and evaluate in KeyPress event.
                    m_nonNumberEntered = true;
                }
            }
        }
    }
    
    private void m_textBox_KeyPress(object sender, KeyPressEventArgs e) {
        // Check for the flag being set in the KeyDown event.
        if (m_nonNumberEntered) {
            // Stop the character from being entered into the control
            // since it is non-numerical.
            e.Handled = true;
        }
    }
    
    [STAThread]
    static void Main(string[] args) {
        Application.EnableVisualStyles();
        Application.SetCompatibleTextRenderingDefault(false);
        Application.Run(new TestForm());
    }
}

 

 

 


 

  (判断逻辑来自KeyEventArgs在MSDN文档上的范例代码)

  得到的文本框外观与一般的TextBox没区别,只是无法由键盘输入数字字符以外的字符。要避免任意字符串被复制-粘贴进来的话,要另外做些判断。这里就不详细写了。

  三、使用MaskedTextBox

  使用例子:

  C#代码  

 

using System;
using System.Windows.Forms;

sealed class TestForm : Form
{
    private MaskedTextBox m_maskedTextBox;
    private ToolTip m_toolTip;
    
    public TestForm() {
        InitializeComponent();
    }
    
    private void InitializeComponent() {
        this.m_maskedTextBox = new MaskedTextBox();
        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 = new ToolTip();
        
        this.ClientSize = new Size(100, 60);
        this.Controls.Add(this.m_maskedTextBox);
        this.PerformLayout();
    }
    
    private void m_maskedTextBox_InputRejected(object sender,
        MaskInputRejectedEventArgs e) {
        toolTip.ToolTipTitle = "Invalid Input";
        toolTip.Show("Only digits (0-9) are allowed.",
            m_maskedTextBox, m_maskedTextBox.Location, 5000);
    }
    
    private void m_maskedTextBox_KeyDown(object sender, KeyEventArgs e) {
        m_toolTip.Hide(maskedTextBox);
    }
    
    [STAThread]
    static void Main(string[] args) {
        Application.EnableVisualStyles();
        Application.SetCompatibleTextRenderingDefault(false);
        Application.Run(new TestForm());
    }
}

 

 

 


 

  这段代码是手写的;要是用VS2005/VS2008的设计器的话,这个例子的所有功能都能直接在设计器里指定。

  输入内容(可以看到分隔符都不需要自己写了,已经写好在输入框里;只要填空就行):

C#中只接受数字输入的控件

  输入内容不符合Mask属性指定的模式时:

C#中只接受数字输入的控件 

  四、使用NumericUpDown

  C#代码   

 

using System;
using System.Drawing;
using System.Windows.Forms;

sealed class TestForm : Form
{
    private NumericUpDown m_numericUpDown;
    
    public TestForm() {
        InitializeComponent();
    }
    
    private void InitializeComponent() {
        this.m_numericUpDown = new NumericUpDown();
        this.m_numericUpDown.Value = 100;
        this.m_numericUpDown.Dock = DockStyle.Fill;
        this.m_numericUpDown.ThousandsSeparator = true;
        this.m_numericUpDown.Maximum = int.MaxValue;
        
        this.ClientSize = new Size(100, 60);
        this.Controls.Add(this.m_numericUpDown);
        this.PerformLayout();
    }
    
    [System.STAThread]
    static void Main(string[] args) {
        Application.EnableVisualStyles();
        Application.SetCompatibleTextRenderingDefault(false);
        Application.Run(new TestForm());
    }
}

 

 

 

 

  这段代码是手写的;要是用VS2005/VS2008的设计器的话,这个例子的所有功能都能直接在设计器里指定。

  NumericUpDown的内容的值可以用Value属性来设置或获取,类型为decimal。

  截图:(输入不符合要求的字符时,默认行为是beep一下,没有工具条的提示)

C#中只接受数字输入的控件 

 

 

  使用NumericUpDown控件。   当需要获取简单数字输入时,在.NET世界中最直接的方法不是去想办法与TextBox搏斗,而应该换个控件来用——NumericUpDown。这个控件不但能接受来自键盘的数字输入,还有一组上下箭头来步进。它包含了许多可以设置的属性,例如显示分隔符逗号的bool ThousandsSeparator、控制最小/最大值的decimal Minimum/decimal Maximum属性等。

  下面对这几种解决方法的其中一些稍微讨论一下。

  一、继承TextBox并覆盖其CreateParams属性

  使用这种方法的NumericTextBox的实现(代码的第1-12行)及用例:

  C#代码   

 

public class NumericTextBox : System.Windows.Forms.TextBox
{
    private const int ES_NUMBER = 0x2000; // ( defined in WinUser.h )
    
    protected override System.Windows.Forms.CreateParams CreateParams {
        get {
            System.Windows.Forms.CreateParams cp = base.CreateParams;            
            cp.Style |= ES_NUMBER;
            return cp;
        }
    }
}

#region use case code sample

sealed class TestForm : System.Windows.Forms.Form
{
    private NumericTextBox m_ntxt;
    
    public TestForm() {
        InitializeComponent();
    }
    
    private void InitializeComponent() {
        this.m_ntxt = new NumericTextBox();
        this.m_ntxt.Dock = System.Windows.Forms.DockStyle.Fill;
        
        this.ClientSize = new System.Drawing.Size(100, 60);
        this.Controls.Add(this.m_ntxt);
        this.PerformLayout();
    }
    
    [System.STAThread]
    static void Main(string[] args) {
        System.Windows.Forms.Application.EnableVisualStyles();
        System.Windows.Forms.Application.SetCompatibleTextRenderingDefault(false);
        System.Windows.Forms.Application.Run(new TestForm());
    }
}

#endregion

 



相关教程