问题
I would like that user could write only numbers from 1 to 49 in edit box. I know how to exclude letters and has possibility to put only numbers but I can't limit it to specific numbers (e.g from 1 to 49 - like in lottery game). I added KeyDown event to edit box and put this code:
if not (KeyChar in ['1'..'9']) then
begin
ShowMessage('Invalid character');
KeyChar := #0;
end;
How can I modify it?
回答1:
Following David's advice, a pattern I often use looks something like this :
function Validate1To49(AStr : string; var Value : integer) : boolean;
begin
result := TryStrToInt(AStr, Value) and
(Value >= 1) and (Value <= 49);
end;
procedure TForm1.Edit1Change(Sender: TObject);
var
tmp : integer;
begin
if Validate1To49(Edit1.Text, tmp) then
Edit1.Color := clWhite
else
Edit1.Color := clRed;
end;
procedure TForm1.Button1Click(Sender: TObject);
var
theValue : integer;
begin
if Validate1To49(Edit1.Text, theValue) then begin
// go ahead and do something with "theValue"
end else
ShowMessage('Value not valid');
end;
Here if the user inputs anything invalid there is immediate visual feedback that is not intrusive like a modal message box. Here I coloured the edit box red, but you can also show/hide or change the colour of a warning label above the edit box with a message detailing the expected input, use a green checkmark, or whatever else seems sensible
This has the benefit that the user can see immediately whether or not their inputs are valid. The validation methods can be wrapped up so that they can be re-used when the user attempts to initiate an action requiring those inputs. At this point I feel it's fine to use a modal messagebox because the user has plainly missed the obvious cues already in front of them. Alternatively, when validating in the OnChange
handler you can simply disable any action controls (like buttons, etc) that would allow the user to proceed. This requires validating all input controls required for the action - again, usually you would wrap the entire validation action into a single method for sensible re-use.
For simple values like integers, a good SpinEdit control can be useful (the VCL one is included in the Samples package - not always installed by default). The above pattern is more flexible, however and can be used for any type of input. A SpinEdit won't provide any feedback, however - the user will simply type and nothing will show up. They may wonder whether the application is broken if there is no clear guidance visible about what the input element will accept.
回答2:
The same question can also be answered in this way also by writing a OnKeyPress event for a Edit box. By this way the user will not be able to enter the number greater than the limit which we define.
procedure TfrmCourse.edtDurationKeyPress(Sender: TObject; var Key: Char);
var
sTextvalue: string;
begin
if Sender = edtDuration then
begin
if (Key = FormatSettings.DecimalSeparator) AND
(pos(FormatSettings.DecimalSeparator, edtDuration.Text) <> 0) then
Key := #0;
if (charInSet(Key, ['0' .. '9'])) then
begin
sTextvalue := TEdit(Sender).Text + Key;
if sTextvalue <> '' then
begin
if ((StrToFloat(sTextvalue) > 12) and (Key <> #8)) then
Key := #0;
end;
end
end;
end;
来源:https://stackoverflow.com/questions/32005290/only-specific-numbers-in-edit-box