I am stuck a bit. My aim is to check and validate my currency field always when it's value changed never mind from the inline code or from the user interface. Is there any validation pattern or sample for it? I want to avaiod calling my validation procedure twice.
Any help or advice would be greatly appreciated.
Here is my example:
type
TMyForm = class(TForm)
ceMyCurrencyEdit: TcxCurrencyEdit;
procedure FormShow(Sender: TObject);
private
{ Private declarations }
procedure SetupMyForm;
public
{ Public declarations }
procedure ValidateMyCurrencyValue;
function IsValidCurrency: Boolean;
end;
procedure TMyForm.ValidateMyCurrencyField;
begin
if not IsValidCurrency then
begin
WarningDlg(
Format(
'InValid value in field: [%s..%s]',
[Formatfloat(ceMyCurrencyEditDisplayFormat, ceMyCurrencyEdit.MinValue),
Formatfloat(ceMyCurrencyEdit.DisplayFormat, ceMyCurrencyEdit.MaxValue)]
)
);
ceMyCurrencyEdit.Value := ceMyCurrencyEdit.MinValue;
end;
end;
function TMyForm.IsValidCurrency: Boolean;
begin
Result := (ceMyCurrencyEdit.Value >= ceMyCurrencyEdit.MinValue) and (ceMyCurrencyEdit.Value <= ceMyCurrencyEdit.MaxValue);
end;
procedure TMyForm.SetupMyForm;
begin
//MaxValue is 100
ceMyCurrencyEdit.Value := 102;
//At this point I need to call ValidateMyCurrencyField to get warning msg and refuse its value
ValidateMyCurrencyField;
end;
procedure TMyForm.FormShow(Sender: TObject);
begin
SetupMyForm;
end;
procedure TMyForm.ceMyCurrencyEditPropertiesEditValueChanged(Sender: TObject);
begin
ValidateMyCurrencyField;
end;
What I want is...
Thanks for the answers!
I'm not sure why you seemed a bit dismissive os @Nil's suggestion, but below
is an example project which shows using the cxCurrencyEdit's validation facility
and using an interposer TcxCurrencyEdit class to record the result of the validation
process in its ValidationState
property.
Obviously you could use the ValidationState property to avoid repeating your validation process or indeed doing it at all if the state says it's valid. However, performance-wise, I very much doubt that you'd be saving yourself anything.
Obviously, the point of the interposer class is to record the validation state
of the control so that you can avoid validating it a second time. Whether you use it in combination with the cxCurrencyEdit1PropertiesValidate
event is entirely up to you.
I leave you to weave this in with your existing code.
Btw, the TEdit control is just there to allow focus to be shifted from the cxCurrencyEdit to trigger its cxCurrencyEdit1PropertiesValidate
event.
UpdateYou asked in a comment about validating a value which is set in code. With an interposer class, it's easy to add a Getter and Setter for the Value property and do the validation in the Setter - see `SetValue below,
type
TCurrencyValidation = (cvNotDone, cvOK, cvInvalid);
TcxCurrencyEdit = class(cxCurrencyEdit.TcxCurrencyEdit)
private
FValidationState : TCurrencyValidation;
function GetValue: Double;
procedure SetValue(const AValue: Double);
protected
property ValidationState : TCurrencyValidation read FValidationState write FValidationState;
published
property Value : Double read GetValue write SetValue;
end;
TForm1 = class(TForm)
cxCurrencyEdit1: TcxCurrencyEdit;
Edit1: TEdit;
procedure FormCreate(Sender: TObject);
procedure cxCurrencyEdit1PropertiesChange(Sender: TObject);
procedure cxCurrencyEdit1PropertiesValidate(Sender: TObject;
var DisplayValue: Variant; var ErrorText: TCaption;
var Error: Boolean);
end;
procedure TForm1.FormCreate(Sender: TObject);
begin
cxCurrencyEdit1.Properties.MinValue := 5;
cxCurrencyEdit1.Properties.MaxValue := 10;
cxCurrencyEdit1.Value := 8;
end;
procedure TForm1.cxCurrencyEdit1PropertiesChange(Sender: TObject);
begin
TcxCurrencyEdit(Sender).ValidationState := cvNotDone;
end;
procedure TForm1.cxCurrencyEdit1PropertiesValidate(Sender: TObject;
var DisplayValue: Variant; var ErrorText: TCaption; var Error: Boolean);
var
Min,
Max : Double;
begin
Min := TcxCurrencyEdit(Sender).Properties.MinValue;
Max := TcxCurrencyEdit(Sender).Properties.MaxValue;
if (DisplayValue >= Min) and (DisplayValue <= Max) then
TcxCurrencyEdit(Sender).ValidationState := cvOK
else
TcxCurrencyEdit(Sender).ValidationState := cvInvalid;
Error := not (TcxCurrencyEdit(Sender).ValidationState = cvOK);
if Error then
ErrorText := 'InvalidValue';
end;
function TcxCurrencyEdit.GetValue: Double;
begin
Result := inherited Value;
end;
procedure TcxCurrencyEdit.SetValue(const AValue: Double);
begin
// insert code to validate AValue here
inherited Value := AValue;
end;