【问题标题】:Extract numbers from a textbox [duplicate]从文本框中提取数字[重复]
【发布时间】:2014-09-25 17:51:07
【问题描述】:

我有一个文本框,其中包含字母和数字以及您可以在键盘上找到的其他符号。我有这个代码,当我手动输入数据时它工作正常,它只允许我输入数字和删除字母。我想要的一切,除了如果复制和粘贴数据都不起作用。下面是我的代码。

private void textBox7_TextChanged(object sender, EventArgs e)
{
    Exception X = new Exception();

    TextBox T = (TextBox)sender;

    T.Text = T.Text.Trim();
    try
    {
        if (T.Text != "-")
        {
            int x = int.Parse(T.Text);
        }
    }
    catch (Exception)
    {
        try
        {
            int CursorIndex = T.SelectionStart - 1;
            T.Text = T.Text.Remove(CursorIndex, 1);

            //Align Cursor to same index
            T.SelectionStart = CursorIndex;
            T.SelectionLength = 0;
        }
        catch (Exception) { }

    }
}

【问题讨论】:

  • 请发布编译代码。你有很多错误的括号,我为你修好了。
  • 尝试添加断点然后再次粘贴文本?...我想知道粘贴是否会抛出整个字符串,而不是手动键入每个字符将调用一次 TextChanged 方法的位置。 ..
  • @Ian 这正是 paste 的作用。
  • 考虑使用 NumericUpDown 控件而不是 TextBox?
  • 你可能还想看看这个问题How do I make a textbox that only accepts numbers?或MSDN上的这篇文章How to: Create a Numeric Text Box

标签: c# numbers text-extraction


【解决方案1】:

您当前代码的问题是您只从光标位置删除最后输入的字符。粘贴超过一个字符的文本会破坏您的算法。

假设您要粘贴 9 个字母,CursorIndex 是 9,您只删除了一个字符(即 T.Text = T.Text.Remove(CursorIndex, 1); 行),剩下 8 个不正确的字符。

更好的方法(不像你的那样过于复杂)如下所示:

private void textBox7_TextChanged(object sender, EventArgs e)
{
    textBox7.Text = string.Concat(textBox7.Text.Where(char.IsDigit));
}

因此,我们在每次更改时将文本替换为包含通过char.IsDigit 测试的每个字符的新文本。然而,光标不会在好的位置。除非需要在字符串中间进行多次编辑,否则最好只绑定一个

textBox1.SelectionStart = textBox1.Text.Length;

在方法结束时,它也会处理粘贴的文本。

要处理当字符- 是文本框中唯一的文本时不想删除它的情况,您可以添加一个明显的if 条件。在全球范围内,它将如下所示:

private void textBox7_TextChanged(object sender, EventArgs e)
{
    if (textbox7.Text != "-")
        textBox7.Text = string.Concat(textBox7.Text.Where(char.IsDigit));

    textBox1.SelectionStart = textBox1.Text.Length;
}

【讨论】:

  • 这不处理第一个字符为负号。
  • @juharr 已编辑,即使该做什么是相当明显的。
【解决方案2】:

试试这个。它将旧值保存在 var 中,如果无法解析新值,则将文本恢复为 old。否则,它将old 更新为最新的有效值。这与您采用的方法不同,但在我看来要简单得多。

string old;
private void textBox7_TextChanged(object sender, EventArgs e) {
    int i;
    if (textBox1.Text == "" || int.TryParse(textBox7.Text, out i)) {
        old = textBox7.Text;
    } else {
        textBox7.Text = old;
    }
}

【讨论】:

    【解决方案3】:

    基本上你的问题是粘贴一个值只会为整个更改调用一次 TextChanged 事件。您的代码依赖于为放入文本框中的每个字符调用的事件。

    听起来您真正想做的就是在可能的负号之后过滤所有非数值。如果是这种情况,您可以这样做。

    private void textBox7_TextChanged(object sender, EventArgs e)
    {
        textBox7.Text = string.Concat(
            textBox7.Text.Trim().Where((c,i)=>char.IsDigit(c) || (i==0 && c=='-')));
    }
    

    此代码使用 Linq 遍历每个字符,在修剪前导和尾随空格之后,如果它是第一个字符,则只保留数字或负号。相当于下面的。

    private void textBox7_TextChanged(object sender, EventArgs e)
    {
        StringBuilder builder = new StringBuilder()
        string trimmed = textBox7.Text.Trim();
        for(int i=0; i<trimmed.Length; i++)
        {
            char c = trimmed.Text[i];
            if(char.IsDigit(c) || (i==0 && c=='-'))
            {
                builder.Append(c);
            }
        }
    
        textBox7.Text = builder.ToString();
    }
    

    【讨论】:

      【解决方案4】:

      要从文本框的文本中删除非数字字符,请尝试使用 Regex.Replace 进行正则表达式替换

      private void numericTextbox_TextChanged(object sender, EventArgs e)
      {
          TextBox tb = (TextBox)sender;
          tb.Text = Regex.Replace(tb.Text, "\\-?[^\d]", "");
      }
      

      这将替换文本中的任何非数字字符(除了前面的破折号,用于负数)每次框中的文本发生变化时,无论用户是直接键入内容还是从其他地方粘贴文本.

      或者,如果您想保留任何破折号(例如,电话号码):

      tb.Text = Regex.Replace(tb.Text, "\\[^-\d]", "");
      

      【讨论】:

      • 这不处理第一个字符为负号。
      • 好点。我已经相应地编辑了我的正则表达式。
      猜你喜欢
      • 1970-01-01
      • 2014-07-11
      • 2012-08-31
      • 2019-12-16
      • 2019-06-29
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多