关于c#:如何制作只接受数字的文本框?

How do I make a textbox that only accepts numbers?

我有一个Windows窗体应用程序,它有一个文本框控件,我只想接受整数值。在过去,我通过重载keypress事件并删除不符合规范的字符来进行这种验证。我已经研究过maskedtextbox控件,但是我想要一个更通用的解决方案,可以使用正则表达式,或者依赖于其他控件的值。

理想情况下,这样做会使按下非数字字符既不会产生结果,也会立即向用户提供关于无效字符的反馈。


两种选择:

  • NumericUpDown代替。NumericUpDown为您过滤,这很好。当然,它也让您的用户能够点击键盘上的上下箭头来增加和减少当前值。

  • 处理适当的键盘事件以防止除数字输入以外的任何输入。我在标准文本框上成功地使用了这两个事件处理程序:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    private void textBox1_KeyPress(object sender, KeyPressEventArgs e)
    {
        if (!char.IsControl(e.KeyChar) && !char.IsDigit(e.KeyChar) &&
            (e.KeyChar != '.'))
        {
                e.Handled = true;
        }

        // only allow one decimal point
        if ((e.KeyChar == '.') && ((sender as TextBox).Text.IndexOf('.') > -1))
        {
            e.Handled = true;
        }
    }
  • 如果您的文本框不允许出现小数点,则可以删除对'.'的检查(以及对多个'.'的后续检查)。如果您的文本框允许负值,您还可以添加对'-'的检查。

    如果要限制用户的位数,请使用:textBox1.MaxLength = 2; // this will allow the user to enter only 2 digits


    仅仅因为在一条线上做事情总是更有趣…

    1
    2
    3
    4
     private void textBox1_KeyPress(object sender, KeyPressEventArgs e)
        {
            e.Handled = !char.IsDigit(e.KeyChar) && !char.IsControl(e.KeyChar);
        }

    注意:这不会阻止用户复制/粘贴到此文本框中。这不是一种安全的清除数据的方法。


    根据上下文和您使用的标记,我假设您正在编写.NET C应用程序。在这种情况下,您可以订阅文本更改事件,并验证每个键笔划。

    1
    2
    3
    4
    5
    6
    7
    8
        private void textBox1_TextChanged(object sender, EventArgs e)
        {
            if (System.Text.RegularExpressions.Regex.IsMatch(textBox1.Text,"[^0-9]"))
            {
                MessageBox.Show("Please enter only numbers.");
                textBox1.Text = textBox1.Text.Remove(textBox1.Text.Length - 1);
            }
        }


    这里有一个简单的独立WinForms自定义控件,它源自标准文本框,只允许System.Int32输入(它可以很容易地适应其他类型,如System.Int64等)。它支持复制/粘贴操作和负数:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    public class Int32TextBox : TextBox
    {
        protected override void OnKeyPress(KeyPressEventArgs e)
        {
            base.OnKeyPress(e);

            NumberFormatInfo fi = CultureInfo.CurrentCulture.NumberFormat;

            string c = e.KeyChar.ToString();
            if (char.IsDigit(c, 0))
                return;

            if ((SelectionStart == 0) && (c.Equals(fi.NegativeSign)))
                return;

            // copy/paste
            if ((((int)e.KeyChar == 22) || ((int)e.KeyChar == 3))
                && ((ModifierKeys & Keys.Control) == Keys.Control))
                return;

            if (e.KeyChar == '\b')
                return;

            e.Handled = true;
        }

        protected override void WndProc(ref System.Windows.Forms.Message m)
        {
            const int WM_PASTE = 0x0302;
            if (m.Msg == WM_PASTE)
            {
                string text = Clipboard.GetText();
                if (string.IsNullOrEmpty(text))
                    return;

                if ((text.IndexOf('+') >= 0) && (SelectionStart != 0))
                    return;

                int i;
                if (!int.TryParse(text, out i)) // change this for other integer types
                    return;

                if ((i < 0) && (SelectionStart != 0))
                    return;
            }
            base.WndProc(ref m);
        }

    更新2017:我的第一个答案有一些问题:

    • 您可以键入比给定类型的整数长的内容(例如2147483648大于Int32.MaxValue);
    • 更一般地说,对于所输入的结果没有真正的验证;
    • 它只处理Int32,您必须为每种类型(Int64等)编写特定的文本框派生控件。

    所以我想出了另一个更通用的版本,它仍然支持复制/粘贴、+和-签名等。

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    public class ValidatingTextBox : TextBox
    {
        private string _validText;
        private int _selectionStart;
        private int _selectionEnd;
        private bool _dontProcessMessages;

        public event EventHandler<TextValidatingEventArgs> TextValidating;

        protected virtual void OnTextValidating(object sender, TextValidatingEventArgs e) => TextValidating?.Invoke(sender, e);

        protected override void WndProc(ref Message m)
        {
            base.WndProc(ref m);
            if (_dontProcessMessages)
                return;

            const int WM_KEYDOWN = 0x100;
            const int WM_ENTERIDLE = 0x121;
            const int VK_DELETE = 0x2e;

            bool delete = m.Msg == WM_KEYDOWN && (int)m.WParam == VK_DELETE;
            if ((m.Msg == WM_KEYDOWN && !delete) || m.Msg == WM_ENTERIDLE)
            {
                DontProcessMessage(() =>
                {
                    _validText = Text;
                    _selectionStart = SelectionStart;
                    _selectionEnd = SelectionLength;
                });
            }

            const int WM_CHAR = 0x102;
            const int WM_PASTE = 0x302;
            if (m.Msg == WM_CHAR || m.Msg == WM_PASTE || delete)
            {
                string newText = null;
                DontProcessMessage(() =>
                {
                    newText = Text;
                });

                var e = new TextValidatingEventArgs(newText);
                OnTextValidating(this, e);
                if (e.Cancel)
                {
                    DontProcessMessage(() =>
                    {
                        Text = _validText;
                        SelectionStart = _selectionStart;
                        SelectionLength = _selectionEnd;
                    });
                }
            }
        }

        private void DontProcessMessage(Action action)
        {
            _dontProcessMessages = true;
            try
            {
                action();
            }
            finally
            {
                _dontProcessMessages = false;
            }
        }
    }

    public class TextValidatingEventArgs : CancelEventArgs
    {
        public TextValidatingEventArgs(string newText) => NewText = newText;
        public string NewText { get; }
    }

    对于Int32,您可以从中派生,如下所示:

    1
    2
    3
    4
    5
    6
    7
    public class Int32TextBox : ValidatingTextBox
    {
        protected override void OnTextValidating(object sender, TextValidatingEventArgs e)
        {
            e.Cancel = !int.TryParse(e.NewText, out int i);
        }
    }

    或者不进行派生,使用如下新的textvalidating事件:

    1
    2
    3
    var vtb = new ValidatingTextBox();
    ...
    vtb.TextValidating += (sender, e) => e.Cancel = !int.TryParse(e.NewText, out int i);

    但好的是它可以与任何字符串和任何验证例程一起工作。


    这正是验证/验证事件的设计目的。

    以下是有关此主题的msdn文章:http://msdn.microsoft.com/en-us/library/system.windows.forms.control.validating.aspx

    tl;dr版本:检查validating事件中的.text属性,当数据无效时设置e.Cancel=True

    当您将e.cancel设置为true时,用户无法离开该字段,但您需要向他们提供某种反馈,说明出现了问题。我把盒子的背景色改成浅红色表示有问题。当使用良好的值调用validation时,请确保将其设置回SystemColors.Window


    尝试使用maskedtextbox。它采用一种简单的掩码格式,因此您可以将输入限制为数字或日期或其他任何格式。


    您可以使用TextChanged事件

    1
    2
    3
    4
    5
    6
    7
    8
    9
    private void textBox_BiggerThan_TextChanged(object sender, EventArgs e)
    {
        long a;
        if (! long.TryParse(textBox_BiggerThan.Text, out a))
        {
            // If not int clear textbox text or Undo() last operation
            textBox_LessThan.Clear();
        }
    }


    这可能有用。它允许"实数"数值,包括正确的小数点和前面的加号或减号。从相关的按键事件中调用它。

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
    90
    91
    92
    93
    94
    95
    96
    97
    98
    99
    100
    101
    102
    103
    104
    105
    106
    107
    108
           private bool IsOKForDecimalTextBox(char theCharacter, TextBox theTextBox)
        {
            // Only allow control characters, digits, plus and minus signs.
            // Only allow ONE plus sign.
            // Only allow ONE minus sign.
            // Only allow the plus or minus sign as the FIRST character.
            // Only allow ONE decimal point.
            // Do NOT allow decimal point or digits BEFORE any plus or minus sign.

            if (
                !char.IsControl(theCharacter)
                && !char.IsDigit(theCharacter)
                && (theCharacter != '.')
                && (theCharacter != '-')
                && (theCharacter != '+')
            )
            {
                // Then it is NOT a character we want allowed in the text box.
                return false;
            }



            // Only allow one decimal point.
            if (theCharacter == '.'
                && theTextBox.Text.IndexOf('.') > -1)
            {
                // Then there is already a decimal point in the text box.
                return false;
            }

            // Only allow one minus sign.
            if (theCharacter == '-'
                && theTextBox.Text.IndexOf('-') > -1)
            {
                // Then there is already a minus sign in the text box.
                return false;
            }

            // Only allow one plus sign.
            if (theCharacter == '+'
                && theTextBox.Text.IndexOf('+') > -1)
            {
                // Then there is already a plus sign in the text box.
                return false;
            }

            // Only allow one plus sign OR minus sign, but not both.
            if (
                (
                    (theCharacter == '-')
                    || (theCharacter == '+')
                )
                &&
                (
                    (theTextBox.Text.IndexOf('-') > -1)
                    ||
                    (theTextBox.Text.IndexOf('+') > -1)
                )
                )
            {
                // Then the user is trying to enter a plus or minus sign and
                // there is ALREADY a plus or minus sign in the text box.
                return false;
            }

            // Only allow a minus or plus sign at the first character position.
            if (
                (
                    (theCharacter == '-')
                    || (theCharacter == '+')
                )
                && theTextBox.SelectionStart != 0
                )
            {
                // Then the user is trying to enter a minus or plus sign at some position
                // OTHER than the first character position in the text box.
                return false;
            }

            // Only allow digits and decimal point AFTER any existing plus or minus sign
            if  (
                    (
                        // Is digit or decimal point
                        char.IsDigit(theCharacter)
                        ||
                        (theCharacter == '.')
                    )
                    &&
                    (
                        // A plus or minus sign EXISTS
                        (theTextBox.Text.IndexOf('-') > -1)
                        ||
                        (theTextBox.Text.IndexOf('+') > -1)
                    )
                    &&
                        // Attempting to put the character at the beginning of the field.
                        theTextBox.SelectionStart == 0
                )
            {
                // Then the user is trying to enter a digit or decimal point in front of a minus or plus sign.
                return false;
            }

            // Otherwise the character is perfectly fine for a decimal value and the character
            // may indeed be placed at the current insertion position.
            return true;
        }

    我一直在努力收集组件来完成WinForms中丢失的内容,这里是:高级表单

    特别是,这是regex文本框的类

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    /// <summary>Represents a Windows text box control that only allows input that matches a regular expression.</summary>
    public class RegexTextBox : TextBox
    {
        [NonSerialized]
        string lastText;

        /// <summary>A regular expression governing the input allowed in this text field.</summary>
        [Browsable(false), EditorBrowsable(EditorBrowsableState.Never)]
        [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
        public virtual Regex Regex { get; set; }

        /// <summary>A regular expression governing the input allowed in this text field.</summary>
        [DefaultValue(null)]
        [Category("Behavior")]
        [Description("Sets the regular expression governing the input allowed for this control.")]
        public virtual string RegexString {
            get {
                return Regex == null ? string.Empty : Regex.ToString();
            }
            set {
                if (string.IsNullOrEmpty(value))
                    Regex = null;
                else
                    Regex = new Regex(value);
            }
        }

        protected override void OnTextChanged(EventArgs e) {
            if (Regex != null && !Regex.IsMatch(Text)) {
                int pos = SelectionStart - Text.Length + (lastText ?? string.Empty).Length;
                Text = lastText;
                SelectionStart = Math.Max(0, pos);
            }

            lastText = Text;

            base.OnTextChanged(e);
        }
    }

    简单地添加像myNumbericTextBox.RegexString ="^(\\d+|)$";这样的东西就足够了。


    只需在文本框中使用此代码:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    private void textBox1_TextChanged(object sender, EventArgs e)
    {

        double parsedValue;

        if (!double.TryParse(textBox1.Text, out parsedValue))
        {
            textBox1.Text ="";
        }
    }

    我在codeplex上为此做了些什么。

    它通过截取textChanged事件来工作。如果结果是一个好数字,它将被存储。如果有问题,最后一个好值将被恢复。源代码有点太大,无法在这里发布,但这里有一个指向处理该逻辑核心的类的链接。


    在定义文本框的网页中,我们可以添加一个仅接受数字的onkeypress事件。它不会显示任何消息,但会防止您输入错误。它对我有效,用户不能输入除数字以外的任何内容。

    1
    2
    <asp:TextBox runat="server" ID="txtFrom"
         onkeypress="if(isNaN(String.fromCharCode(event.keyCode))) return false;">

    只需使用一个NumericUpDown控件,并将那些丑陋的上下按钮设置为false的可见性。

    1
    numericUpDown1.Controls[0].Visible = false;

    NumericUpDown实际上是包含一个"数字调整框"(上下按钮)、一个文本框和一些代码的控件集合,用于验证和wange将它们结合在一起。

    标记:

    1
    YourNumericUpDown.Controls[0].visible = false

    将隐藏按钮,同时保持底层代码处于活动状态。

    虽然不是一个显而易见的解决方案,但它是简单有效的。如果您想这样做,.Controls[1]会隐藏文本框部分。


    看看WinForm中的输入处理

    我已经在文本框中发布了使用processCmdKey和onKeyPress事件的解决方案。这些注释向您展示了如何使用regex来验证按键并适当地阻止/允许。


    嗨,您可以在文本框的TextChanged事件中执行类似的操作。

    这是一个演示

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
        private void textBox1_TextChanged(object sender, EventArgs e)
        {
            string actualdata = string.Empty;
            char[] entereddata = textBox1.Text.ToCharArray();
            foreach (char aChar in entereddata.AsEnumerable())
            {
                if (Char.IsDigit(aChar))
                {
                    actualdata = actualdata + aChar;
                    // MessageBox.Show(aChar.ToString());
                }
                else
                {
                    MessageBox.Show(aChar +" is not numeric");
                    actualdata.Replace(aChar, ' ');
                    actualdata.Trim();
                }
            }
            textBox1.Text = actualdata;
        }


    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    private void txt3_KeyPress(object sender, KeyPressEventArgs e)
    {
        for (int h = 58; h <= 127; h++)
        {
            if (e.KeyChar == h)             //58 to 127 is alphabets tat will be         blocked
            {
                e.Handled = true;
            }
        }
        for(int k=32;k<=47;k++)
        {
            if (e.KeyChar == k)              //32 to 47 are special characters tat will
            {                                  be blocked
                e.Handled = true;
            }
        }
    }

    试试这个很简单


    使用Fabio Iotti回答中描述的方法,我创建了一个更通用的解决方案:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    public abstract class ValidatedTextBox : TextBox {
        private string m_lastText = string.Empty;
        protected abstract bool IsValid(string text);
        protected sealed override void OnTextChanged(EventArgs e) {
            if (!IsValid(Text)) {
                var pos = SelectionStart - Text.Length + m_lastText.Length;
                Text = m_lastText;
                SelectionStart = Math.Max(0, pos);
            }
            m_lastText = Text;
            base.OnTextChanged(e);
        }
    }

    "validatedTextBox",其中包含所有重要的验证行为。剩下要做的就是继承这个类,并用需要的任何验证逻辑重写"isvalid"方法。例如,使用这个类,可以创建"regexedtextbox",它只接受与特定正则表达式匹配的字符串:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    public abstract class RegexedTextBox : ValidatedTextBox {
        private readonly Regex m_regex;
        protected RegexedTextBox(string regExpString) {
            m_regex = new Regex(regExpString);
        }
        protected override bool IsValid(string text) {
            return m_regex.IsMatch(Text);
        }
    }

    之后,从"regexedTextBox"类继承,我们可以轻松创建"positiveNumberTextBox"和"positivefloatingPointNumberTextBox"控件:

    1
    2
    3
    4
    5
    6
    7
    8
    public sealed class PositiveNumberTextBox : RegexedTextBox {
        public PositiveNumberTextBox() : base(@"^\d*$") { }
    }

    public sealed class PositiveFloatingPointNumberTextBox : RegexedTextBox {
        public PositiveFloatingPointNumberTextBox()
            : base(@"^(\d+" + CultureInfo.CurrentCulture.NumberFormat.NumberDecimalSeparator + @")?\d*$") { }
    }

    您可以使用textchanged/keypress事件,使用regex过滤数字并采取一些操作。


    整数和浮点数都需要被接受,包括负数。

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    private void textBox1_KeyPress(object sender, KeyPressEventArgs e)
    {
        // Text
        string text = ((Control) sender).Text;

        // Is Negative Number?
        if (e.KeyChar == '-' && text.Length == 0)
        {
            e.Handled = false;
            return;
        }

        // Is Float Number?
        if (e.KeyChar == '.' && text.Length > 0 && !text.Contains("."))
        {
            e.Handled = false;
            return;
        }

        // Is Digit?
        e.Handled = (!char.IsDigit(e.KeyChar) && !char.IsControl(e.KeyChar));
    }


    似乎目前这个问题的许多答案都是手动解析输入文本。如果您要查找特定的内置数字类型(例如intdouble),为什么不将工作委托给该类型的TryParse方法呢?例如:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    public class IntTextBox : TextBox
    {
        string PreviousText ="";
        int BackingResult;

        public IntTextBox()
        {
            TextChanged += IntTextBox_TextChanged;
        }

        public bool HasResult { get; private set; }

        public int Result
        {
            get
            {
                return HasResult ? BackingResult : default(int);
            }
        }

        void IntTextBox_TextChanged(object sender, EventArgs e)
        {
            HasResult = int.TryParse(Text, out BackingResult);

            if (HasResult || string.IsNullOrEmpty(Text))
            {
                // Commit
                PreviousText = Text;
            }
            else
            {
                // Revert
                var changeOffset = Text.Length - PreviousText.Length;
                var previousSelectionStart =
                    Math.Max(0, SelectionStart - changeOffset);

                Text = PreviousText;
                SelectionStart = previousSelectionStart;
            }
        }
    }

    如果需要更通用但仍与Visual Studio的设计器兼容的内容:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    public class ParsableTextBox : TextBox
    {
        TryParser BackingTryParse;
        string PreviousText ="";
        object BackingResult;

        public ParsableTextBox()
            : this(null)
        {
        }

        public ParsableTextBox(TryParser tryParse)
        {
            TryParse = tryParse;

            TextChanged += ParsableTextBox_TextChanged;
        }

        public delegate bool TryParser(string text, out object result);

        public TryParser TryParse
        {
            set
            {
                Enabled = !(ReadOnly = value == null);

                BackingTryParse = value;
            }
        }

        public bool HasResult { get; private set; }

        public object Result
        {
            get
            {
                return GetResult<object>();
            }
        }

        public T GetResult<T>()
        {
            return HasResult ? (T)BackingResult : default(T);
        }

        void ParsableTextBox_TextChanged(object sender, EventArgs e)
        {
            if (BackingTryParse != null)
            {
                HasResult = BackingTryParse(Text, out BackingResult);
            }

            if (HasResult || string.IsNullOrEmpty(Text))
            {
                // Commit
                PreviousText = Text;
            }
            else
            {
                // Revert
                var changeOffset = Text.Length - PreviousText.Length;
                var previousSelectionStart =
                    Math.Max(0, SelectionStart - changeOffset);

                Text = PreviousText;
                SelectionStart = previousSelectionStart;
            }
        }
    }

    最后,如果您想要完全通用的东西,而不关心设计器支持:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    public class ParsableTextBox<T> : TextBox
    {
        TryParser BackingTryParse;
        string PreviousText;
        T BackingResult;

        public ParsableTextBox()
            : this(null)
        {
        }

        public ParsableTextBox(TryParser tryParse)
        {
            TryParse = tryParse;

            TextChanged += ParsableTextBox_TextChanged;
        }

        public delegate bool TryParser(string text, out T result);

        public TryParser TryParse
        {
            set
            {
                Enabled = !(ReadOnly = value == null);

                BackingTryParse = value;
            }
        }

        public bool HasResult { get; private set; }

        public T Result
        {
            get
            {
                return HasResult ? BackingResult : default(T);
            }
        }

        void ParsableTextBox_TextChanged(object sender, EventArgs e)
        {
            if (BackingTryParse != null)
            {
                HasResult = BackingTryParse(Text, out BackingResult);
            }

            if (HasResult || string.IsNullOrEmpty(Text))
            {
                // Commit
                PreviousText = Text;
            }
            else
            {
                // Revert
                var changeOffset = Text.Length - PreviousText.Length;
                var previousSelectionStart =
                    Math.Max(0, SelectionStart - changeOffset);

                Text = PreviousText;
                SelectionStart = previousSelectionStart;
            }
        }
    }

    这一个与复制和粘贴、拖放、向下键一起工作,防止溢出,非常简单

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    public partial class IntegerBox : TextBox
    {
        public IntegerBox()
        {
            InitializeComponent();
            this.Text = 0.ToString();
        }

        protected override void OnPaint(PaintEventArgs pe)
        {
            base.OnPaint(pe);
        }

        private String originalValue = 0.ToString();

        private void Integerbox_KeyPress(object sender, KeyPressEventArgs e)
        {
            originalValue = this.Text;
        }

        private void Integerbox_TextChanged(object sender, EventArgs e)
        {
            try
            {
                if(String.IsNullOrWhiteSpace(this.Text))
                {
                    this.Text = 0.ToString();
                }
                this.Text = Convert.ToInt64(this.Text.Trim()).ToString();
            }
            catch (System.OverflowException)
            {
                MessageBox.Show("Value entered is to large max value:" + Int64.MaxValue.ToString(),"Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
                this.Text = originalValue;
            }
            catch (System.FormatException)
            {                
                this.Text = originalValue;
            }
            catch (System.Exception ex)
            {
                this.Text = originalValue;
                MessageBox.Show(ex.Message,"Error", MessageBoxButtons.OK , MessageBoxIcon.Error);
            }
        }      
    }

    我也在寻找只检查文本框中数字的最佳方法,而按键的问题在于它不支持右键单击或剪贴板复制粘贴,所以我想出了这个代码来验证光标离开文本字段的时间,同时也检查空字段。(改编版纽盖)

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    private void txtFirstValue_MouseLeave(object sender, EventArgs e)
    {
        int num;
        bool isNum = int.TryParse(txtFirstValue.Text.Trim(), out num);

        if (!isNum && txtFirstValue.Text != String.Empty)
        {
            MessageBox.Show("The First Value You Entered Is Not a Number, Please Try Again","Invalid Value Detected", MessageBoxButtons.OK, MessageBoxIcon.Error);
            txtFirstValue.Clear();
        }
    }


    不要忘记用户可以将无效文本粘贴到TextBox中。

    如果您想限制这一点,请遵循以下代码:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    private void ultraTextEditor1_TextChanged(object sender, EventArgs e)
    {
        string append="";
        foreach (char c in ultraTextEditor1.Text)
        {
            if ((!Char.IsNumber(c)) && (c != Convert.ToChar(Keys.Back)))
            {

            }
            else
            {
                append += c;
            }
        }

        ultraTextEditor1.Text = append;
    }

    我会在按键事件中处理它。

    1
    2
    3
    4
    5
    6
    7
    8
    void TextBox_KeyDown(object sender, KeyEventArgs e)
            {
                char c = Convert.ToChar(e.PlatformKeyCode);
                if (!char.IsDigit(c))
                {
                    e.Handled = true;
                }
            }


    很抱歉叫醒死者,但我想可能有人会发现这对以后的参考有用。

    我就是这样处理的。它处理浮点数,但可以很容易地为整数修改。

    基本上你只能按0-9和。

    在之前只能有一个0。

    忽略所有其他字符并保留光标位置。

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
        private bool _myTextBoxChanging = false;

        private void myTextBox_TextChanged(object sender, EventArgs e)
        {
            validateText(myTextBox);
        }

        private void validateText(TextBox box)
        {
            // stop multiple changes;
            if (_myTextBoxChanging)
                return;
            _myTextBoxChanging = true;

            string text = box.Text;
            if (text =="")
                return;
            string validText ="";
            bool hasPeriod = false;
            int pos = box.SelectionStart;
            for (int i = 0; i < text.Length; i++ )
            {
                bool badChar = false;
                char s = text[i];
                if (s == '.')
                {
                    if (hasPeriod)
                        badChar = true;
                    else
                        hasPeriod = true;
                }
                else if (s < '0' || s > '9')
                    badChar = true;

                if (!badChar)
                    validText += s;
                else
                {
                    if (i <= pos)
                        pos--;
                }
            }

            // trim starting 00s
            while (validText.Length >= 2 && validText[0] == '0')
            {
                if (validText[1] != '.')
                {
                    validText = validText.Substring(1);
                    if (pos < 2)
                        pos--;
                }
                else
                    break;
            }

            if (pos > validText.Length)
                pos = validText.Length;
            box.Text = validText;
            box.SelectionStart = pos;
            _myTextBoxChanging = false;
        }

    下面是一个快速修改的int版本:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
        private void validateText(TextBox box)
        {
            // stop multiple changes;
            if (_myTextBoxChanging)
                return;
            _myTextBoxChanging = true;

            string text = box.Text;
            if (text =="")
                return;
            string validText ="";
            int pos = box.SelectionStart;
            for (int i = 0; i < text.Length; i++ )
            {
                char s = text[i];
                if (s < '0' || s > '9')
                {
                    if (i <= pos)
                        pos--;
                }
                else
                    validText += s;
            }

            // trim starting 00s
            while (validText.Length >= 2 && validText.StartsWith("00"))
            {
                validText = validText.Substring(1);
                if (pos < 2)
                    pos--;
            }

            if (pos > validText.Length)
                pos = validText.Length;
            box.Text = validText;
            box.SelectionStart = pos;
            _myTextBoxChanging = false;
        }


    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    int Number;
    bool isNumber;
    isNumber = int32.TryPase(textbox1.text, out Number);

    if (!isNumber)
    {
        (code if not an integer);
    }
    else
    {
        (code if an integer);
    }

    3解

    1)

    1
    2
    3
    4
    5
    6
    7
    8
    //Add to the textbox's KeyPress event
    //using Regex for number only textBox

    private void txtBox_KeyPress(object sender, KeyPressEventArgs e)
    {
    if (!System.Text.RegularExpressions.Regex.IsMatch(e.KeyChar.ToString(),"\\d+"))
    e.Handled = true;
    }

    2)来自msdn的另一个解决方案

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    // Boolean flag used to determine when a character other than a number is entered.
    private bool nonNumberEntered = false;
    // Handle the KeyDown event to determine the type of character entered into the     control.
    private void textBox1_KeyDown(object sender, KeyEventArgs e)
    {
    // Initialize the flag to false.
    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.
                nonNumberEntered = true;
            }
        }
    }

    }

    1
    2
    3
    4
    5
    6
    7
    8
    private void textBox1_KeyPress(object sender, KeyPressEventArgs e)
    {
        if (nonNumberEntered == true)
        {
           MessageBox.Show("Please enter number only...");
           e.Handled = true;
        }
    }

    来源:http://msdn.microsoft.com/en-us/library/system.windows.forms.control.keypress(v=vs.90).aspx

    3)使用maskedtextbox:http://msdn.microsoft.com/en-us/library/system.windows.forms.maskedtextbox.aspx


    简单的回答:

    1
    2
    3
    4
    5
    _textBox.TextChanged += delegate(System.Object o, System.EventArgs e)
    {
        TextBox _tbox = o as TextBox;
        _tbox.Text = new string(_tbox.Text.Where(c => (char.IsDigit(c)) || (c == '.')).ToArray());
    };

    故障保护和简单的"递归"方法,可用于多个文本框。

    它阻止错误的键盘输入字符和粘贴的值等。它只接受整数,最大的数字长度是字符串类型的最大长度(即int,真正的long!)

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    public void Check_If_Int_On_TextChanged(object sender, EventArgs e)
    {
       // This method checks that each inputed character is a number. Any non-numeric
       // characters are removed from the text

       TextBox textbox = (TextBox)sender;

       // If the text is empty, return
       if (textbox.Text.Length == 0) { return; }

       // Check the new Text value if it's only numbers
       byte parsedValue;
       if (!byte.TryParse(textbox.Text[(textbox.Text.Length - 1)].ToString(), out parsedValue))
       {
          // Remove the last character as it wasn't a number
          textbox.Text = textbox.Text.Remove((textbox.Text.Length - 1));

          // Move the cursor to the end of text
          textbox.SelectionStart = textbox.Text.Length;
        }
     }

    我喜欢简明扼要的代码

    1
    2
    3
    4
        private void xmm_textbox_KeyPress(object sender, KeyPressEventArgs e) {
            double x;
            e.Handled = !double.TryParse(((TextBox)sender).Text, out x);
        }

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    Here is a simple solution that works for me.

    public static bool numResult;
        public static bool checkTextisNumber(string numberVal)
        {
            try
            {
                if (numberVal.Equals("."))
                {
                    numResult = true;
                }
                else if (numberVal.Equals(""))
                {
                    numResult = true;
                }
                else
                {
                    decimal number3 = 0;
                    bool canConvert = decimal.TryParse(numberVal, out number3);
                    if (canConvert == true)
                    {
                        numResult = true;
                    }
                    else
                        numResult = false;
                }

            }
            catch (System.Exception ex)
            {
                numResult = false;
            }
            return numResult;
        }
        string correctNum;
        private void tBox_NumTester_TextChanged(object sender, TextChangedEventArgs e)
        {


            if(checkTextisNumber(tBox_NumTester.Text))
            {
                correctNum = tBox_NumTester.Text;
            }
            else
            {
                tBox_NumTester.Text = correctNum;
            }

        }

    我已经为各种验证创建了一个可重用的文本框扩展类,并考虑共享它。

    您所需要做的就是引发一个textchange事件,然后调用validate方法。看起来是这样的:

    1
    2
    3
    4
    private void tbxAmount_TextChanged(object sender, EventArgs e)
    {
        tbxAmount.Validate(TextValidator.ValidationType.Amount);
    }

    这是扩展类:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
    90
    91
    public static class TextValidator
    {
        public enum ValidationType
        {
            Amount,
            Integer
        }

        /// <summary>
        /// Validate a textbox on text change.
        /// </summary>
        /// <param name="tbx"></param>
        /// <param name="validationType"></param>
        public static void Validate(this TextBox tbx, ValidationType validationType)
        {
            PerformValidation(tbx, validationType);
            tbx.Select(tbx.Text.Length, 0);
        }


        private static void PerformValidation(this TextBox tbx, ValidationType validationType)
        {
            char[] enteredString = tbx.Text.ToCharArray();
            switch (validationType)
            {
                case ValidationType.Amount:
                    tbx.Text = AmountValidation(enteredString);
                    break;

                case ValidationType.Integer:
                    tbx.Text = IntegerValidation(enteredString);
                    break;

                default:
                    break;
            }

            tbx.SelectionStart = tbx.Text.Length;
        }



        private static string AmountValidation(char[] enteredString)
        {
            string actualString = string.Empty;
            int count = 0;
            foreach (char c in enteredString.AsEnumerable())
            {
                if (count >= 1 && c == '.')
                { actualString.Replace(c, ' '); actualString.Trim(); }
                else
                {
                    if (Char.IsDigit(c))
                    {
                        actualString = actualString + c;
                    }

                    if (c == '.')
                    {
                        actualString = actualString + c; count++;
                    }

                    else
                    {
                        actualString.Replace(c, ' ');
                        actualString.Trim();
                    }
                }
            }
            return actualString;
        }


        private static string IntegerValidation(char[] enteredString)
        {
            string actualString = string.Empty;
            foreach (char c in enteredString.AsEnumerable())
            {
                if (Char.IsDigit(c))
                {
                    actualString = actualString + c;
                }
                else
                {
                    actualString.Replace(c, ' ');
                    actualString.Trim();
                }
            }
            return actualString;
        }
    }

    您可以在这里找到完整的代码


    这是我的围裙:

  • 使用LINQ(易于修改过滤器)
  • 复制/粘贴校样代码
  • 按禁止字符时保留插入符号位置
  • 接受左零
  • 还有任何尺寸的号码

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    private void numeroCuenta_TextChanged(object sender, EventArgs e)
    {
        string org = numeroCuenta.Text;
        string formated = string.Concat(org.Where(c => (c >= '0' && c <= '9')));
        if (formated != org)
        {
            int s = numeroCuenta.SelectionStart;
            if (s > 0 && formated.Length > s && org[s - 1] != formated[s - 1]) s--;
            numeroCuenta.Text = formated;
            numeroCuenta.SelectionStart = s;
        }
    }

  • 在"按钮单击"中,您可以按for循环检查文本框的文本:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    char[] c = txtGetCustomerId.Text.ToCharArray();
    bool IsDigi = true;

    for (int i = 0; i < c.Length; i++)
         {
           if (c[i] < '0' || c[i] > '9')
          { IsDigi = false; }
         }
     if (IsDigi)
        {
         // do something
        }