С++/CLI: валидация TextBox и перехват нажатий клавиш формой
Представим себе проект Windows Forms
с обычным текстовым полем TextBox
. Требуется разрешить вводить в поле только определённые данные, скажем, вещественные числа. Как и в QT,
мы можем не применять в .NET довольно неуклюжие решения, связанные с проверкой вводимых данных "на лету" при помощи обработки событий нажатия клавиш, а воспользоваться вместо этого событием Validating
, позволяющим проверить данные после ввода.
Кстати, при успешном результате проверки после этого происходит ещё и событие Validated
, которое тоже можно программировать. Вот простой кусочек кода для Validating
:
private: bool ValidNumber(String ^s) { if (s->Trim()->Length == 0) return false; Double d; bool Is_Num = Double::TryParse(textBox1->Text, System::Globalization::NumberStyles::Number, System::Globalization::NumberFormatInfo::CurrentInfo, d); return Is_Num; } private: System::Void textBox1_Validating(System::Object^ sender, System::ComponentModel::CancelEventArgs^ e) { if (!ValidNumber(textBox1->Text)) { e->Cancel = true; textBox1->Select(0, textBox1->Text->Length); } }
Что касается второй проблемы, для того, чтобы форма получала все события клавиш, на каком бы активном элементе они не происходили,
нужно установить свойство формы KeyPreview = true
.
Тогда все события сначала будет получать форма, а затем передавать управление событиям, назначенным элементам.
Если нужно, чтобы после обработки события в форме управление не передавалось дальше другим элементам,
можно использовать в обработчике формы e->Handled = true;
что будет означать, что событие уже
обработано и остальные события того же типа, скажем, KeyPress
обрабатывать не нужно.
Вот пример кода для события KeyUp
формы:
private: System::Void MyForm1_KeyUp(System::Object^ sender, System::Windows::Forms::KeyEventArgs^ e) { int c = e->KeyValue; String^ Digit; if (c >= (int)Keys::D0 && c <= (int)Keys::D9) Digit = (c - (int)Keys::D0).ToString(); else if (c == 190) Digit = "."; else if (c == 187) Digit = ","; //...и т.д., потом что-то делаем со строкой Digit e->Handled = true; }
Здесь просто примитивно разрешаются нажатия на форме цифровых клавиш, точки и запятой.
В обработчике события от клавиатуры для находящегося в форме textBox1
тоже должно быть e->Handled = true;
, чтобы не происходило "дублирования" символов.
private: System::Void textBox1_KeyPress(System::Object^ sender, System::Windows::Forms::KeyPressEventArgs^ e) { e->Handled = true; }
Ну и, конечно, не смешиваем все способы контроля в одном программном модуле :)
10.09.2019, 17:24 [2710 просмотров]