`
RednaxelaFX
  • 浏览: 3047929 次
  • 性别: Icon_minigender_1
  • 来自: 海外
社区版块
存档分类
最新评论

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

    博客分类:
  • C#
阅读更多
在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行)及用例:
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的字符时的样子:

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

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

=========================================================================================

二、自行监听KeyDown事件

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

最简单来说类似这样:
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

使用例子:
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的设计器的话,这个例子的所有功能都能直接在设计器里指定。

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

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


=========================================================================================

四、使用NumericUpDown

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一下,没有工具条的提示)
4
1
分享到:
评论
5 楼 碧海山城 2009-07-01  
MaskedTextBox 的提示符如果可以不显示出来就比较强大了。。现在用的很郁闷
4 楼 RednaxelaFX 2008-04-07  
java998 写道
这个控件我们公司的产品里面早就用到了.

呃呵呵,我这边也只是做个笔记而已……最近在写些东西,这个记下来给同学看。
.NET 2.0也出来那么久了,这种WinForm控件早就被专业的摸透了…… ^ ^
3 楼 java998 2008-04-07  
这个控件我们公司的产品里面早就用到了.
2 楼 RednaxelaFX 2008-04-06  
lwwin 写道
大家不太用纯WIN32 api写LIB么?

那要看写什么库吧……

嘛,还有好几篇草稿在后面。这两天在弄Ruby+wxRuby+wxWidgets+wxFormBuilder相关,看什么时候能写完。
1 楼 lwwin 2008-04-06  
不知道有没有适合WIN32SDK直接用的控件库……

对于界面偶一直抱着偷懒的态度来着=3=,所以最好有个轮子=v=+

大家不太用纯WIN32 api写LIB么?

话说不用MFC和.NET的话,也有很多人用跨平台的LIB去了…………

相关推荐

    c# .net Wince 数字输入控件 数字键盘

    这个控件通常被称为“数字输入控件”,它的设计目标是模拟HMI(人机界面)屏幕上的数字输入框,提供一个友好的、易于触控操作的界面。 在Wince系统上,由于硬件资源有限且多为触控操作,因此,设计一个高效且直观的...

    C#Text只能输入数字自定义控件

    在C#编程中,开发人员有时需要创建特定类型的输入控件,例如只允许用户输入数字的文本框。这种自定义控件可以确保数据的准确性和一致性,尤其在处理财务、统计或其他数值相关的应用中。本教程将深入讲解如何在C#中...

    c# winform textbox控件只能输入数字的几种方法

    在C# WinForms开发中,有时我们需要限制TextBox控件只接受数字输入,这对于处理数值数据的应用程序来说尤为重要。本文将详细介绍几种实现这一功能的方法,并深入分析每种方法的工作原理及适用场景。 ### 方法一:...

    自制控件:C#中TextBox控件只允许输入数字

    例如,在财务应用或数学计算程序中,我们可能希望某个文本框(`TextBox`)仅能接受数字输入,包括整数和小数。这种限制可以通过自定义控件来实现,从而提高应用程序的质量和用户体验。 #### 技术细节 本案例中展示...

    winform C# Led数字显示控件

    本篇将详细介绍如何在C#环境下创建一个自定义的LED数字显示控件,并探讨其液晶显示功能,以及如何调整大小和颜色。 首先,我们需要创建一个新的用户控件(UserControl)项目。在Visual Studio中,选择"文件" -&gt; ...

    C# TextBox中只允许输入数字的解决方法

    在C#编程中,TextBox控件是最常用的用户输入控件之一,它允许用户输入文本。然而,有时我们希望限制用户只能输入数字,例如在创建一个简单的计算器或数据录入界面时。下面将详细介绍如何实现C# TextBox控件只允许...

    C# IP地址输入控件

    通过以上描述,我们可以看到"C# IP地址输入控件"的实现涉及了控件设计、事件处理、数据验证、用户交互等多个方面,是C# Winform开发中的一个实用技巧。通过这个控件,我们可以提供更加直观、准确的IP地址输入方式,...

    c# 数字键盘控件

    下面我们将详细探讨如何创建和使用C#数字键盘控件,以及相关的编程概念和技术。 首先,我们需要理解控件的基本概念。在Windows Forms或WPF应用中,控件是用户界面的基础元素,如按钮、文本框等,它们提供了与用户...

    C#写的虚拟键盘输入用户自定义控件+源码+调用实例

    本资源提供了一个基于C#编写的虚拟键盘控件,适用于多种应用场景,如无物理键盘的触摸设备或者增强安全性输入等。这个控件允许用户自定义其外观和功能,以满足特定的需求。 首先,我们要理解什么是虚拟键盘。虚拟...

    车牌号码输入控件,通过点击输入

    本文将深入探讨一个特定的UI组件——车牌号码输入控件,该控件允许用户通过点击来输入车牌号码,支持简称、字母和数字的自定义输入。我们将详细讨论它的设计原理、功能特性以及在实际应用中的实现方法。 首先,车牌...

    C# 绚丽仪表控件,开关控件,彩色圆形按钮,晶体管数字控件源码(已测试)

    在本文中,我们将深入探讨C#编程中的一些高级UI元素,特别是那些用于创建工业风格界面的控件。这些控件包括“绚丽仪表控件”、“开关控件”、“彩色圆形按钮”以及“晶体管数字控件”。这些源码是经过实际测试的,...

    C#.net中TextBox输入浮点型数字

    ### C#.NET中限制TextBox仅能输入浮点型数字的方法 在C#.NET开发中,经常需要对用户输入的数据进行格式控制,特别是当输入框(`TextBox`)用于收集数值时,确保用户只能输入合法的浮点数是非常重要的。本文将详细...

    NumTextBox.rar_C# 数字控件

    这样,用户界面就会有一个只接受数字输入的文本框。 开发者还可以利用`NumTextBox`提供的事件来实现业务逻辑,比如在用户输入完成后更新数据库或其他操作: ```csharp numBox.TextChanged += (sender, e) =&gt; { ...

    C#winform控件textbox按键输入控制.rar

    1. **数字输入限制**:如果要确保TextBox只接受数字输入,可以在`KeyPress`事件中检查`e.KeyChar`的值。如果它不是数字或退格键,就取消事件处理,阻止其他字符输入。 ```csharp private void textBox1_KeyPress...

    C#文本框TextBox只有输入数字

    综上所述,通过结合`KeyPress`、`TextChanged`等事件,并利用`TryParse`系列方法,我们可以有效地限制C#的TextBox控件只接受数字输入,同时提供良好的用户体验。在实际项目中,可以根据需求进行适当的调整和扩展。

    C#文本框只能输入数字

    在C#编程语言中,文本框(TextBox)是Windows Forms应用程序中最常用的控件之一,用于接收用户的输入。但在某些应用场景下,我们可能需要限制用户在文本框中输入的内容类型,例如仅允许输入数字。这种需求常见于需要...

    c# winForm Ip地址输入控件

    总之,创建一个"C# WinForm IP地址输入控件"涉及到设计UI布局,实现输入验证,以及提供方便的接口供其他代码使用。通过这样的自定义控件,开发者可以在Windows应用程序中提供一个符合用户习惯的IP地址输入体验。

    利用C#.NET实现PC机与研华ADAM-4050模块数字量输入实例(MSComm控件)

    在本文中,我们将深入探讨如何使用C#.NET编程语言与研华ADAM-4050模块进行数字量输入的实现。研华ADAM-4050是一款工业级的数据采集模块,它提供了数字量输入/输出功能,常用于自动化控制、监控系统等场合。而C#.NET...

    C#自定义IP控件(修正)

    在这个场景下,“C#自定义IP控件(修正)”是一个针对IP地址输入的定制控件,它解决了在前一版本中遇到的问题,主要是关于用户无法在清空输入框后输入数字0以及IP地址验证的改进。 IP地址通常由四个0到255之间的...

Global site tag (gtag.js) - Google Analytics