I set the TSpinEdit.MaxValue to 100 but when the program runs, it lets the user enter values over 100 - when the number is entered manually (instead of using the spins). There is any way to limit the value to MaxValue without writing code?
The problem is that when the user enters a wrong value, this can result in a RageCheckError or something similar.
procedure TFrmMain.spnMaxFileSizeChange(Sender: TObject);
begin
PlaylistCtrl.BigFileThresh:= spnMaxFileSize.Value * KB;
end;
This could be fixed with something like:
if spnMaxFileSize.Value> spnMaxFileSize.MaxValue
then spnMaxFileSize.Value:= spnMaxFileSize.MaxValue;
...but I don't really want to manually add this line for each control on my form. All the fun of "visual programming" will be lost :)
Two possible solution:
TYPE
TMySpinEdit = class(TSpinEdit) { Fixes the OnChange MinValue/MaxValue issue }
private
Timer: TTimer;
FOnChanged: TNotifyEvent;
procedure TimesUp(Sender: TObject);
public
constructor Create (AOwner: TComponent);override;
destructor Destroy;override;
procedure Change; override;
published
property OnChanged: TNotifyEvent read FOnChanged write FOnChanged;
end;
constructor TMySpinEdit.Create(AOwner: TComponent);
begin
inherited;
Timer:= TTimer.Create(Self);
Timer.OnTimer:= TimesUp;
Timer.Interval:= 2500; { allow user 2.5 seconds to enter a new correct value }
end;
destructor TMySpinEdit.Destroy;
begin
FreeAndNil(Timer);
inherited;
end;
procedure TMySpinEdit.Change;
begin
Timer.Enabled:= FALSE;
Timer.Enabled:= TRUE;
end;
procedure TMySpinEdit.TimesUp;
begin
Timer.Enabled:= FALSE;
if (MaxValue<> 0) AND (Value> MaxValue) then Value:= MaxValue;
if (MinValue<> 0) AND (Value< MinValue) then Value:= MinValue;
if Assigned(FOnChanged) then FOnChanged(Self);
end;
Code not tested yet (to be compiled).
The other solution would be:
TYPE
TMySpinEdit = class(TSpinEdit)
public
procedure Change; override;
end;
IMPLEMENTATION
procedure TMySpinEdit .Change;
begin
if (Value > MaxValue) OR (Value < MinValue) then
begin
Color:= clRed;
EXIT; { Out of range value. Don't trigger the OnChange event. }
end;
Color:= clWindow;
inherited;
end;
Update
I wrote an extension for TSpinEdit. This control offers an extra event called OnChanged which is called 1200ms (See the Delay property) after the user entered the value.
https://github.com/GabrielOnDelphi/Delphi-LightSaber/blob/main/cvSpinEditDelayed.pas