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::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
仍会自动禁用小于您所需阈值的值。
【讨论】:
非常感谢雷米先生。你所有的答案对我来说都很有价值,也提高了我的编程知识。当然,你的编码技巧真的很棒:)。无论如何,你能教我如何将IdThrottler's Bits
转换为KB/sec
以便我可以应用IDM 的speed limiter 的风格吗?
一个字节有 8 位,一个 KB 有 1024 个字节。基础数学。例如,如果您想将速度限制为 50 KB/秒,您可以将 BitsPerSec
设置为 (8 * 1024 * 50) = 409600 位。
我知道,但我的意思是输入TSpinEdit
或TEdit
的速度值是在kilobytes
而不是bits
。你有额外的TiDHTTP
功能吗?或者您是否有计划更新TiDHTTP
以便在BytesPerSec
中而不是BitsPerSec
中有一个选项?。以上是关于TEdit 和 TCheckBox 验证的主要内容,如果未能解决你的问题,请参考以下文章
RAD Studio XE5 移动应用程序中的 TCheckBox
在 delphi XE8 Firemonkey TCheckBox.GetStyleObject 上永远不会被调用,为啥?
delphi一次性批量在TScrollBox中显示N个复选框TCheckBox的源码