4

我想创建一个 TextChanged 事件来检查输入文本是否符合特定条件,如果不符合则删除最后输入的字符。在这种情况下,标准是数字、1 个小数和 1 个小数。

我正在为数字和小数测试正则表达式并遇到问题。我尝试了几种不同的表达式(我自己写的很糟糕,所以它们是从其他各种堆栈溢出问题中挑选出来的),结果每次都是一样的。它接受数字就好了,但它不接受小数。任何帮助将不胜感激!

        string isNumber = @"^\d{1,9}(\.\d{1,9})?$";

        private void TextBox_TextChanged(object sender, EventArgs e)
        {
            TextBox text = (TextBox)sender;

            Match match = Regex.Match(text.Text, isNumber);

            if (!match.Success)
            {
                if (text.Text.Length > 1)
                    text.Text = text.Text.Substring(0, text.Text.Length - 1);
                else
                    text.Text = "";

                text.Select(text.Text.Length, 0); //set cursor to the end 
                                                  //of the string
            }
        }
4

3 回答 3

7

我认为问题在于您正在尝试在用户键入时逐个字符地验证数字,但是如果值暂时无效,则无法键入有效的十进制数。

考虑当用户输入值时会发生什么1.2

  1. 用户键入字符1
  2. 验证触发是因为文本框的值发生了变化。
  3. 1是有效的小数,因此验证通过。
  4. 用户继续输入,添加小数点字符.
  5. 验证再次触发,因为文本框的值发生了变化。
  6. 1.根据正则表达式,它不是有效的小数,所以最后一个字符被删除。
  7. 文本框的值现在恢复为1
  8. 用户感到沮丧。转到第 4 步。

如您所见,无法输入小数点。但是,如果您尝试更改正则表达式以允许小数点存在而没有后面的数字,那么如果用户在输入小数点后停止然后提交表单,则您可能会得到一个无效的值。

所以关键是,使用逐个字符的验证方案不适用于小数。更好的方法是允许用户在框中输入他们想要的任何内容,然后在用户完成输入后进行验证。您可以通过验证文本框何时失去焦点或何时提交表单来做到这一点。

于 2013-07-22T22:01:36.550 回答
1

这不是最漂亮的,但它似乎可以满足您的需求:

^(\d{1,9}\.|)\d{1,9}(\.(\d{1,9})?)$

我应该注意,这不适用于以小数开头的数字。

于 2013-07-22T22:03:07.010 回答
1

至少有一个问题是您尝试做什么(以及如何)(就像布赖恩指出的那样好),您可能的意思是只允许文本框的前 3 个字符为格式“1.3”并删除char 如果它在那个位置不是正确的。如果你真的打算这样做,你可以这样做(如果用户在成功后放置另一个字符,在这种情况下是第四个字符,我没有为这种情况放置任何代码):

        string isNumber = @"^[1-9]{1}\.[1-9]{1}$";
        private void textBox1_TextChanged(object sender, EventArgs e)
        {
            TextBox text = (TextBox)sender;

            Match match;

            switch (text.Text.Length)
            {
                case 1:
                    if (char.IsDigit(text.Text[0]))
                        break;
                    else
                        text.Text = "";
                    break;
                case 2:
                    if (char.IsPunctuation(text.Text[1]))
                        break;
                    else
                    {
                        text.Text = text.Text.Remove(text.Text.Length - 1, 1);
                        text.Select(text.Text.Length, 0); 
                    }
                    break;
                case 3:
                    match = Regex.Match(text.Text, isNumber);
                    if (!match.Success)
                    {
                        text.Text = text.Text.Remove(text.Text.Length - 1);
                        text.Select(text.Text.Length, 0); 
                    }
                    else
                        MessageBox.Show("Success!!!!!");
                    break;
            }

        }

如您所见,我逐个字符地检查,直到长度达到 3,然后我检查正则表达式。

于 2013-07-23T00:59:18.467 回答