TEdit и TCheckBox Validations
Моя цель заключается в том, чтобы пользователи никогда не смогли проверить TCheckBox
когда число вводится в TEdit
менее 7 цифр. Кроме того, это TCheckBox
никогда не может быть проверено, когда TEdit
пустует.
Проблема моих кодов иногда TCheckBox
все еще можно проверить, хотя TEdit
пустует.
Более того, моя другая цель состоит в том, чтобы кнопка запуска никогда не выполнялась или всегда будет отображать сообщение об ошибке, если кнопка запуска нажата, когда проверяется TCheckBox, в то время как TEdit
пустует.
Проблема в том, какие коды я должен поставить в кнопку запуска?
Я использую следующий код:
//--------------------------------------------------------------------------------
void __fastcall TForm::MyTEditBoxKeyPress(TObject *Sender, System::WideChar &Key)
{
if( Key == VK_BACK ) return;
if((Key < '1') || (Key > '9'))
{
MessageDlg("Please enter number only.",mtInformation, TMsgDlgButtons()<< mbOK, 0);
Key = 0;
}
}
//--------------------------------------------------------------------------------
void __fastcall TForm::MyTEditBoxExit(TObject *Sender)
{
if (MyTEditBox->Text.Length() < 7) {
MessageDlg("Please enter at least 7 digit.",mtInformation, TMsgDlgButtons()<< mbOK, 0);
}
}
//--------------------------------------------------------------------------------
void __fastcall TForm::MyCheckBoxClick(TObject *Sender)
{
if (MyCheckBox->Tag == 0 ) {
MyCheckBox->Tag = 1;
if (MyTEditBox->Text.Length() >= 7)
MyCheckBox->Checked = true;
IdThrottler->BitsPerSec = StrToInt64(MyTEditBox->Text);
}
else {
MyCheckBox->Tag = 0;
if (MessageDlg("Please enter at least 7 digit.",mtInformation, TMsgDlgButtons()<< mbOK, 0) == mrYes)
MyCheckBox->Checked = false;
}
}
1 ответ
Во-первых, троттлер BitsPerSec
собственность int
не __int64
так что вы должны использовать StrtoInt()
вместо StrToInt64()
,
Вы устанавливаете TCheckBox::Enabled
недвижимость в TCheckBox::OnClick
событие, поэтому пользователь должен фактически нажать на TCheckBox
чтобы он обновился сам. Если пользователь только набрал TEdit
и никогда не нажимает на TCheckBox
, он никогда не будет обновлен.
Если вы не хотите, чтобы пользователь нажимал на TCheckBox
вообще если TEdit
текст достаточно, вы должны использовать TEdit::OnChange
событие, чтобы установить TCheckBox::Enabled
собственности, и избавиться от вашего TCheckBox::Tag
обработка в целом:
void __fastcall TMyForm::MyTEditBoxChange(TObject *Sender)
{
MyCheckBox->Enabled = (MyTEditBox->GetTextLen() >= 7);
}
void __fastcall TMyForm::MyCheckBoxClick(TObject *Sender)
{
if (MyCheckBox->Checked)
IdThrottler->BitsPerSec = StrToInt(MyTEditBox->Text);
else
IdThrottler->BitsPerSec = 0;
}
Обратите внимание, что если пользователь может ввести более 6 цифр, это не означает, что Text
представляет значение int
значение. В этой ситуации StrToInt()
поднимет исключение.
Другой способ справиться с этим - добавить TActionList
в форму, создайте в ней пользовательское действие, назначьте это действие TCheckBox::Action
свойство, а затем использовать TAction::OnUpdate
событие, чтобы установить TAction::Enabled
свойство (которое будет включать / отключать TCheckBox
):
void __fastcall TMyForm::MyActionUpdate(TObject *Sender)
{
MyAction1->Enabled = (MyTEditBox->GetTextLen() >= 7);
}
Преимущество этого подхода заключается в том, что TCheckBox::Enabled
свойство будет обновляться автоматически и в режиме реального времени без необходимости вручную реагировать на изменения в TEdit
совсем.
С учетом сказанного, если вы используете современную версию C++Builder, TEdit
имеет NumbersOnly
имущество. Когда установлено значение true, вам не нужно фильтровать нажатия клавиш в TEdit::OnKeyPress
В этом случае ОС не позволит пользователю вводить для вас нецифровые символы (кроме того, когда вы фильтруете вручную, вы не позволяете пользователю вводить 0
цифры, что неправильно).
Если вы действительно должны позволить пользователю вводить номер через TEdit
и если TEdit::NumbersOnly
свойство недоступно в вашей версии C++Builder, у вас все еще есть пара других опций (которые вы должны рассмотреть в любом случае, даже в современных версиях C++ Builder):
сделать
TEdit
только для чтения, прикрепитьTUpDown
к нему черезTUpDown::Associate
собственности, и назначить соответствующиеTUpDown::Min
а такжеTUpDown::Max
значения по мере необходимости. ИспользоватьTUpDown::Position
свойство для обновления троттлераBitsPerSec
имущество:void __fastcall TMyForm::MyActionUpdate(TObject *Sender) { MyAction1->Enabled = (MyUpDown->Position > 999999); } void __fastcall TMyForm::MyUpDownClick(TObject *Sender, TUDBtnType Button) { if ((MyCheckBox->Enabled) && (MyCheckBox->Checked)) IdThrottler->BitsPerSec = MyUpDown->Position; else IdThrottler->BitsPerSec = 0; }
Может также использовать
TTrackBar
который устанавливаетTUpDown::Value
свойство с большими приращениями, так что пользователю не нужно нажимать стрелки вверх / вниз для более мелких настроек:void __fastcall TMyForm::MyTrackBarChange(TObject *Sender) { MyUpDown->Position = MyTrackBar->Position; MyUpDownClick(NULL, btNext); }
Не беспокойтесь об использовании
TEdit
совсем. ИспользоватьTCSpinEdit
или жеTSpinEdit
вместо этого (в зависимости от вашей версии C++Builder). Пользователь может вводить числа, и он будет отклонять нечисловой ввод. Это обеспечивает стрелки вверх / вниз, какTUpDown
, для внесения небольших корректировок. И это имеетValue
свойство, которое возвращает / принимаетint
вместоString
так же, какTUpDown::Position
имущество.void __fastcall TMyForm::MyActionUpdate(TObject *Sender) { MyAction1->Enabled = (MySpinEdit->Value > 999999); } void __fastcall TMyForm::MySpinEditChange(TObject *Sender) { if ((MyCheckBox->Enabled) && (MyCheckBox->Checked)) IdThrottler->BitsPerSec = MySpinEdit->Value; else IdThrottler->BitsPerSec = 0; }
В любом случае, пользователь вообще не может вводить нечисловые значения, а TCheckBox
все еще автоматически отключается для значений, которые меньше, чем желаемый порог.