2014-09-25 56 views
-3

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

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) { } 

    } 
} 
+0

请寄出编译的代码。你有很多我为你修复的错误括号。 – gunr2171 2014-09-25 17:56:15

+0

尝试添加一个断点,然后再次粘贴文本?...我不知道是否粘贴在整个字符串中,而不是手动输入TextChanged方法每个字符将被调用一次...... – Ian 2014-09-25 18:00:40

+0

@Ian这就是究竟是什么粘贴。 – juharr 2014-09-25 18:04:58

回答

0

从文本框的文本中删除非数字字符,使用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]", ""); 
+0

这不处理作为负号的第一个字符。 – juharr 2014-09-25 18:14:26

+0

好点。我相应地编辑了我的正则表达式。 – 2014-09-25 19:06:51

0

基本上你的问题是,粘贴值仅适用于整个更换一次调用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(); 
} 
0

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

假设您粘贴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; 
} 
+0

这不处理第一个字符是负号。 – juharr 2014-09-25 18:12:49

+0

@juharr编辑,即使做什么是相当不明显的。 – 2014-09-25 18:16:19

0

试试这个。它将旧值保存在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; 
    } 
}