TEdit 和 TCheckBox 验证

TEdit and TCheckBox Validations

我的目的是当号码输入TEdit少于7位时,用户将永远无法检查TCheckBox。此外,当 TEdit 为空时,永远无法检查此 TCheckBox

我的代码的一个问题是,尽管 TEdit 为空,但有时 TCheckBox 仍然可以检查。

此外,我的另一个目标是在TEdit为空的情况下,如果在选中TCheckBox时单击开始按钮,则启动按钮永远无法执行或始终显示错误消息。

问题是我应该在开始按钮中输入什么代码?

我正在使用以下代码:

//--------------------------------------------------------------------------------
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;
    }
}

首先,油门的 BitsPerSec 属性 是 int,而不是 __int64,所以你应该使用 StrtoInt() 而不是 StrToInt64().

您正在 TCheckBox::OnClick 事件中设置 TCheckBox::Enabled 属性,因此用户必须实际单击 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 属性(这将 enable/disable TCheckBox):

void __fastcall TMyForm::MyActionUpdate(TObject *Sender)
{
    MyAction1->Enabled = (MyTEditBox->GetTextLen() >= 7);
}

这种方法的好处是 TCheckBox::Enabled 属性 将自动实时更新,而无需手动对 TEdit 中的更改做出反应。

也就是说,如果您使用的是现代版本的 C++Builder,TEdit 有一个 NumbersOnly 属性。当设置为 true 时,您不必再在 TEdit::OnKeyPress 事件中过滤击键,OS 将阻止用户为您输入非数字字符(此外,当您手动过滤时,您不允许用户输入 0 位数字,这是错误的。

如果您确实必须允许用户通过 TEdit 输入数字,并且如果 TEdit::NumbersOnly 属性 在您的 C++Builder 版本中不可用,您还有几个其他选项(无论如何你都应该考虑,即使在现代 C++Builder 版本中):

  1. TEdit 设置为只读,通过 TUpDown::Associate 属性 附加一个 TUpDown,并分配适当的 TUpDown::MinTUpDown::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 属性,这样用户不必按 up/down 箭头进行更多的小调整:

    void __fastcall TMyForm::MyTrackBarChange(TObject *Sender)
    {
        MyUpDown->Position = MyTrackBar->Position;
        MyUpDownClick(NULL, btNext);
    }
    
  2. 根本不用 TEdit。请改用 TCSpinEditTSpinEdit(取决于您的 C++Builder 版本)。用户可以输入数字,它会拒绝非数字输入。它提供 up/down 箭头,如 TUpDown,用于进行小的调整。它有一个 Value 属性 那个 returns/accepts 一个 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 仍然会自动禁用小于您所需阈值的值。