如何通过代码恢复字段的最后一个值?

时间:2019-01-10 14:10:13

标签: delphi dataset delphi-2007

TField.OnValidate事件处理程序中,我必须要求用户确认新键入的值。 如果他不确定,我想恢复上一个值。

目前,我正在按照以下示例进行操作:

procedure  TForm1.FldOnValidate(AField : TField);
begin
  if(MessageDlg('Are you sure?', mtConfirmation, [mbYes, mbNo], 0) = mrNo) then
  begin
    Abort;
  end;
end;

procedure TForm1.FormCreate(Sender: TObject);
var
  Dst : TClientDataSet;
  Dsc : TDataSource;
  Fld : TStringField;
  Grid : TDBGrid;
begin
  //dataset
  Dst := TClientDataSet.Create(Self);
  Dst.FieldDefs.Add('TEST', ftString, 20);
  Dst.CreateDataSet();
  Dst.Active := True;
  Fld := Dst.Fields[0] as TStringField;
  Dst.Append();
  Fld.AsString := 'a';
  Dst.Post();
  Fld.OnValidate := FldOnValidate;

  //datasource
  Dsc := TDataSource.Create(Self);
  Dsc.DataSet := Dst;

  //grid
  Grid := TDBGrid.Create(Self);
  Grid.DataSource := Dsc;
  Grid.Columns.Add.FieldName := Fld.FieldName;
  Grid.Align := alClient;
  Grid.Parent := Self;
end;

测试步骤:

  1. 运行应用程序
  2. 输入“ b”
  3. 按“ Enter”键
  4. 按“是”按钮
  5. 输入“ c”
  6. 按“ Enter”键
  7. 按“否”按钮
  8. 按“ Esc”键

'b'将恢复。

我想避免第8点,当用户按下'No'按钮时,我想自动重置先前的值。

尝试:

我尝试了以下方法,但是OldValue'c'(而且我认为这不是做我需要的正确方法)。

procedure  TForm1.FldOnValidate(AField : TField);
begin
  if(MessageDlg('Are you sure?', mtConfirmation, [mbYes, mbNo], 0) = mrNo) then
  begin
    AField.OnValidate := nil;
    try
      AField.AsVariant := AField.OldValue;
    finally
      AField.OnValidate := FldOnValidate;
    end;
    Abort;
  end;
end;

1 个答案:

答案 0 :(得分:2)

使用TField.DataSet.Cancel作为

procedure  TForm1.FldOnValidate(AField : TField);
begin
  if MessageDlg('Are you sure?', mtConfirmation, [mbYes, mbNo], 0) = mrNo then
      Sender.DataSet.Cancel;
end;
  • 如果单击“是”按钮,则OnValidate事件处理程序不会引发异常,则将数据写入当前记录缓冲区,然后调用OnChange事件处理程序。

  • 如果单击“否”按钮,则将调用 Cancel 过程,如果尚未发布对活动记录的所有修改,则将被取消。

为什么?

来自 docs

  

要拒绝OnValidate事件处理程序中字段的当前值,请引发异常。

因此,由于您不想引发异常,因此这是唯一的方法。

OnValidate 事件处理程序用于验证数据,而不用于确认。

如果使用最新版本的Delphi,这会很容易,因为它提供了


更新:

  if MessageDlg('Validate?', mtConfirmation, [mbYes, mbNo], 0) = mrNo then
    Sender.DataSet.Cancel
      else
        Sender.DataSet.Post;

步骤:

  • 键入'b',然后单击Yes
  • 键入'c',然后单击No
  • 该值将根据需要返回到'b'
  

使用TFDMemTable在Delphi 10西雅图进行了测试。