避免调用重复验证
Avoid calling duplication for validation
我有点卡住了。我的目标是始终检查和验证我的货币字段,当它的值发生变化时,不管是从内联代码还是从用户界面。是否有任何验证模式或样本?我想避免调用我的验证程序两次。
如有任何帮助或建议,我们将不胜感激。
这是我的例子:
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;
我想要的是...
感谢您的回答!
我不确定为什么你似乎有点不屑一顾 os @Nil 的建议,但在下面
是一个示例项目,它显示了使用 cxCurrencyEdit 的验证工具
并使用 interposer TcxCurrencyEdit class 记录验证结果
在其 ValidationState
属性.
中处理
显然你可以使用 ValidationState 属性 来避免重复
你的验证过程,或者如果国家说它是有效的,就真的这样做。
但是,就性能而言,我非常怀疑您是否会自救
任何东西。
很明显,interposer class的重点是记录验证状态
控件,这样您就可以避免对其进行第二次验证。是否与 cxCurrencyEdit1PropertiesValidate
事件结合使用完全取决于您。
我让你将它与你现有的代码结合起来。
顺便说一句,TEdit 控件就在那里允许焦点从 cxCurrencyEdit 转移到触发它的 cxCurrencyEdit1PropertiesValidate
事件。
更新您在评论中询问了验证代码中设置的值。和
一个 interposer class,很容易为值 属性 添加一个 Getter 和 Setter
并在 Setter 中进行验证 - 请参阅下面的 `SetValue,
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;
我有点卡住了。我的目标是始终检查和验证我的货币字段,当它的值发生变化时,不管是从内联代码还是从用户界面。是否有任何验证模式或样本?我想避免调用我的验证程序两次。
如有任何帮助或建议,我们将不胜感激。
这是我的例子:
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;
我想要的是...
感谢您的回答!
我不确定为什么你似乎有点不屑一顾 os @Nil 的建议,但在下面
是一个示例项目,它显示了使用 cxCurrencyEdit 的验证工具
并使用 interposer TcxCurrencyEdit class 记录验证结果
在其 ValidationState
属性.
显然你可以使用 ValidationState 属性 来避免重复 你的验证过程,或者如果国家说它是有效的,就真的这样做。 但是,就性能而言,我非常怀疑您是否会自救 任何东西。
很明显,interposer class的重点是记录验证状态
控件,这样您就可以避免对其进行第二次验证。是否与 cxCurrencyEdit1PropertiesValidate
事件结合使用完全取决于您。
我让你将它与你现有的代码结合起来。
顺便说一句,TEdit 控件就在那里允许焦点从 cxCurrencyEdit 转移到触发它的 cxCurrencyEdit1PropertiesValidate
事件。
更新您在评论中询问了验证代码中设置的值。和 一个 interposer class,很容易为值 属性 添加一个 Getter 和 Setter 并在 Setter 中进行验证 - 请参阅下面的 `SetValue,
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;