首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >Delphi TField.OnValidate可以在不引发异常的情况下恢复原始值吗?

Delphi TField.OnValidate可以在不引发异常的情况下恢复原始值吗?
EN

Stack Overflow用户
提问于 2018-10-18 08:25:06
回答 2查看 2.1K关注 0票数 4

我通常将验证逻辑实现为:

代码语言:javascript
复制
procedure TMyDM.IBQueryAMOUNTValidate(
  Sender: TField);
begin
  inherited;
  if Sender.AsFloat>100
    then raise Exception.Create('Amount is too large!');
end;

问题是,是否有可能不在OnValidate中引发OnValidate(这将停止进一步的处理),而是恢复OnValidate中的原始值,并继续执行CheckBrowseMode/Post调用的OnChangeCheckBrowseMode和所有GUI更新。

当然,我知道我可以将OnValidate逻辑替换为处理OldValueNewValueOnChange逻辑,但在我看来,代码会更干净--我坚持使用OnValidate

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2018-10-18 13:28:10

除了引发异常以拒绝Sender的值之外,不要使用Sender来做任何事情。

要了解原因,请设置一个简单的测试应用程序,该应用程序由一个包含字段ID (Integer)和名称(String(20))、TDataSource、TDBNavigator、TDBGrid和TDBEdit的字段组成。添加以下代码:

代码语言:javascript
复制
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;

在DBEdit中编译、运行并输入'x‘(没有引号)。然后单击DBNavigator上的Save。

请注意,编辑已被取消,但'x‘仍保留在DBEdit中。这是德尔菲10.2.3,顺便说一句。在D7时代,情况甚至更糟-- DB网格中的错误行会显示'x'!

另一件事是,在TDataSet的方法中从未真正调用OnValidate,只有后代,例如TClientDataSet。因此,通常不能保证在任何时候调用OnValidate --这取决于dataset类型的作者是否正确。

所以我认为你的问题的答案是“不”,离开OnValidate来引发例外,但不会有更多。

票数 5
EN

Stack Overflow用户

发布于 2018-10-18 12:48:54

在我看来,OnValidate事件的唯一目的是引发异常。来自Delphi (http://docwiki.embarcadero.com/Libraries/Berlin/en/Data.DB.TField.OnValidate):

若要从OnValidate事件处理程序拒绝字段的当前值,请引发异常. 如果写入数据不会引发异常,则调用OnChange事件处理程序以允许对更改作出响应。

对于验证任务,我使用OnSetText事件,这使我有可能在新的值不可接受的情况下无声地恢复原始值。

票数 4
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/52869890

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档