Как сделать текстовое поле, принимающее только цифры (C# WinForms)?
Всем привет! Я новичок в C# и WinForms, делаю простое приложение для ввода возраста пользователя. Мне нужно, чтобы в текстовое поле можно было вводить только цифры, а буквы и другие символы игнорировались. Я пробовал использовать int.TryParse после нажатия кнопки, но это неудобно — пользователь может ввести "abc123" и узнать об ошибке только после клика. Хочется, чтобы невалидные символы вообще не появлялись в поле во время ввода.
Вот мой текущий код, который проверяет значение по кнопке:
private void buttonOk_Click(object sender, EventArgs e)
{
string input = textBoxAge.Text;
if (int.TryParse(input, out int age))
{
MessageBox.Show($"Ваш возраст: {age}");
}
else
{
MessageBox.Show("Введите только цифры!");
}
}
Как сделать, чтобы пользователь физически не мог ввести буквы? Я слышал про событие KeyPress, но не понимаю, как его правильно применить. Подскажите, пожалуйста, решение для WinForms. Заранее спасибо!
Решение через событие KeyPress
Самый распространённый и простой способ — обработать событие KeyPress текстового поля. В этом событии мы проверяем, является ли введённый символ цифрой или управляющим символом (Backspace, Delete и т.д.). Если символ не подходит — отменяем его ввод.
Вот полный пример для вашего случая:
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
// Подписываемся на событие KeyPress
textBoxAge.KeyPress += TextBoxAge_KeyPress;
}
private void TextBoxAge_KeyPress(object sender, KeyPressEventArgs e)
{
// Разрешаем только цифры и управляющие клавиши (Backspace)
if (!char.IsControl(e.KeyChar) && !char.IsDigit(e.KeyChar))
{
e.Handled = true; // Отменяем ввод символа
}
}
private void buttonOk_Click(object sender, EventArgs e)
{
if (int.TryParse(textBoxAge.Text, out int age))
{
MessageBox.Show($"Ваш возраст: {age}");
}
else
{
MessageBox.Show("Введите только цифры!");
}
}
}
Как это работает:
e.KeyChar— символ, который пользователь пытается ввести.char.IsControl(e.KeyChar)— проверяет, является ли символ управляющим (Backspace, Delete, Enter, стрелки). Такие символы мы пропускаем.char.IsDigit(e.KeyChar)— проверяет, является ли символ цифрой (0-9).- Если символ не цифра И не управляющий — устанавливаем
e.Handled = true. Это отменяет его появление в текстовом поле.
Важные дополнения:
- Если нужно разрешить ввод десятичных чисел (с точкой или запятой), добавьте проверку на эти символы. Например, для дробных чисел:
if (e.KeyChar == '.' || e.KeyChar == ','). - Для ввода отрицательных чисел можно разрешить знак минуса, но только в начале строки:
if (e.KeyChar == '-' && textBox.SelectionStart == 0). - Можно также обработать событие
TextChangedдля дополнительной валидации, ноKeyPress— самый прямой путь.
Альтернатива с MaskedTextBox:
В WinForms есть специальный элемент MaskedTextBox, который позволяет задать маску ввода. Для цифр маска будет "00000" (пять цифр) или "99999" (необязательные цифры). Это удобно для фиксированного формата, но менее гибко, чем KeyPress.
Дополнительный подход: обработка TextChanged + Regex
Метод с KeyPress — самый простой, но у него есть недостаток: пользователь может вставить текст из буфера обмена (Ctrl+V), который содержит нецифровые символы. KeyPress не перехватывает вставку.
Чтобы решить эту проблему, можно добавить обработку события TextChanged и фильтровать текст после каждого изменения:
private void textBoxAge_TextChanged(object sender, EventArgs e)
{
// Удаляем все нецифровые символы
string filtered = Regex.Replace(textBoxAge.Text, @"[^\d]", "");
if (filtered != textBoxAge.Text)
{
int selectionStart = textBoxAge.SelectionStart;
textBoxAge.Text = filtered;
// Восстанавливаем позицию курсора
textBoxAge.SelectionStart = Math.Min(selectionStart, filtered.Length);
}
}
Этот код использует регулярное выражение [^\d], которое находит всё, кроме цифр. Если в тексте есть лишние символы, они удаляются, а курсор сохраняет своё положение. Лучше комбинировать оба подхода: KeyPress для блокировки ввода с клавиатуры и TextChanged для защиты от вставки.