2014-09-25 5 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

+0

Попробуйте добавить точку останова, а затем снова вставить текст? ... Интересно, бросает ли паста всю строку, в отличие от ввода вручную, когда метод TextChanged будет вызываться один раз за символ ... – Ian

+0

@Ian Это точно, что делает паста. – juharr

ответ

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

+0

Хорошая точка. Я соответствующим образом отредактировал свое регулярное выражение. –

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

+0

@juharr отредактирован, даже если что делать, это довольно пошло. –

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; 
    } 
} 
Смежные вопросы