我通常将验证逻辑实现为: procedure TMyDM.IBQueryAMOUNTValidate( Sender: TField);begin inherited; if Sender.AsFloat100 then raise Exception.Create('Amount is too large!');end; 问题是 – 是否有可能不在OnValidate(停止进
procedure TMyDM.IBQueryAMOUNTValidate( Sender: TField); begin inherited; if Sender.AsFloat>100 then raise Exception.Create('Amount is too large!'); end;
问题是 – 是否有可能不在OnValidate(停止进一步处理)中引发Exception,而是在OnValidate中恢复静默原始值并继续OnChange,CheckBrowseMode以及CheckBrowseMode / Post调用的所有GUI更新?
当然,我知道我总是可以用处理OldValue和NewValue的OnChange逻辑替换OnValidate逻辑,但在我看来,我坚持使用OnValidate代码会更清晰.
除了引发异常拒绝之外,不要使用OnValidate做任何事情发件人的价值.
要了解原因,请设置一个简单的测试应用程序,其中包含一个带有字段ID(整数)和名称(字符串(20))的TClientDataSet,TDataSource,
名称字段的TDBNavigator,TDBGrid和TDBEdit.添加以下代码:
procedure TForm1.ClientDataSet1NameValidate(Sender: TField); begin if Sender.AsString = 'x' then Sender.DataSet.Cancel; end; procedure TForm1.FormCreate(Sender: TObject); begin ClientDataSet1.CreateDataSet; ClientDataSet1.InsertRecord([1, 'a']); ClientDataSet1.InsertRecord([2, 'b']); ClientDataSet1.InsertRecord([3, 'c']); end;
编译,运行并输入“x”(不带引号)到DBEdit中.然后单击DBNavigator上的Save.
请注意,编辑已取消,但“x”仍保留在DBEdit中.这是
在Delphi 10.2.3中,顺便说一下.回到D7天,情况更糟 – 这是错误的排
DB网格会显示’x’!
另一件事是OnValidate实际上从未在TDataSet的方法中被调用,
只有后代,例如的TClientdataSet.所以一般都不能保证
OnValidate将在所有或正确的时间被调用 – 由数据集类型的作者决定是否正确.
所以我认为你的q的答案是“不”,让OnValidate提出例外但不再提出.