TEdit 和 TCheckBox 验证

Posted

技术标签:

【中文标题】TEdit 和 TCheckBox 验证【英文标题】:TEdit and TCheckBox Validations 【发布时间】:2015-08-12 22:28:57 【问题描述】:

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

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

此外,我的另一个目标是启动按钮永远无法执行,或者如果在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;
    

【问题讨论】:

为什么不使用Checked而不是复选框点击功能中的Tag 【参考方案1】:

首先,节流器的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 事件设置@987654344 @ 属性(将启用/禁用TCheckBox):

void __fastcall TMyForm::MyActionUpdate(TObject *Sender)

    MyAction1->Enabled = (MyTEditBox->GetTextLen() >= 7);

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

话虽如此,如果您使用的是现代版本的 C++Builder,TEdit 具有NumbersOnly 属性。当设置为 true 时,您不必再过滤 TEdit::OnKeyPress 事件中的击键,操作系统将阻止用户为您输入非数字字符(此外,当您手动过滤时,您不允许用户输入0 数字,这是错误的)。

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

    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 属性,这样用户只需按向上/向下箭头即可进行小的调整:

    void __fastcall TMyForm::MyTrackBarChange(TObject *Sender)
    
        MyUpDown->Position = MyTrackBar->Position;
        MyUpDownClick(NULL, btNext);
    
    

    根本不用TEdit。请改用TCSpinEditTSpinEdit(取决于您的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 仍会自动禁用小于您所需阈值的值。

【讨论】:

非常感谢雷米先生。你所有的答案对我来说都很有价值,也提高了我的编程知识。当然,你的编码技巧真的很棒:)。无论如何,你能教我如何将IdThrottler's Bits 转换为KB/sec 以便我可以应用IDM 的speed limiter 的风格吗? ‎ 一个字节有 8 位,一个 KB 有 1024 个字节。基础数学。例如,如果您想将速度限制为 50 KB/秒,您可以将 BitsPerSec 设置为 (8 * 1024 * 50) = 409600 位。 我知道,但我的意思是输入TSpinEditTEdit的速度值是在kilobytes而不是bits。你有额外的TiDHTTP 功能吗?或者您是否有计划更新TiDHTTP 以便在BytesPerSec 中而不是BitsPerSec 中有一个选项?。

以上是关于TEdit 和 TCheckBox 验证的主要内容,如果未能解决你的问题,请参考以下文章

RAD Studio XE5 移动应用程序中的 TCheckBox

在 delphi XE8 Firemonkey TCheckBox.GetStyleObject 上永远不会被调用,为啥?

delphi一次性批量在TScrollBox中显示N个复选框TCheckBox的源码

通过 Javascript CheckBox 验证文本框

DELPHI中如何使用ADOQUERY和TEDIT,TMEMO操作数据库。

Delphi 之 编辑框控件(TEdit)