浏览结果时,FireDac FDQuery提交更改了DataFields

时间:2015-10-24 12:46:45

标签: delphi firedac

我有一个绑定到FDConnection的FDQuery。

我正在使用DB Data-Aware组件在我的表单上显示数据。

每当我使用FPQuery.Next,.Prior,......它会在结果之间浏览。

一切都很好。

除非我更改一个值(例如John - &gt; Jane),然后使用FPQuery.Next获取下一个结果,它保存将更改后的值提交给db,即使我没有FDQuery1.CommitUpdates。< / p>

当用户按下nbPost-Button或使用FDQuery1.CommitUpdates时,是否有办法只保存更改的DataField,而在浏览结果时使用NOT?

enter image description here

谢谢!

2 个答案:

答案 0 :(得分:2)

就像我在评论中所说,标准TDataset行为是在导航到另一个之前调用其.Post方法来保存对当前行的更改。这发生在TDataSet.CheckBrowseMode中的例程Data.DB.Pas中,该例程在任何导航操作之前调用。如果没有派生自定义TDataset后代,则无法更改此内容。

(来自Data.DB.Pas)

procedure TDataSet.CheckBrowseMode;
begin
  CheckActive;
  DataEvent(deCheckBrowseMode, 0);
  case State of
    dsEdit, dsInsert:
      begin
        UpdateRecord;
        if Modified then Post else Cancel;
      end;
    dsSetKey:
      Post;
  end;
end;

当然,TDataSet有一个BeforePost事件,所以尝试使用它取消更改可能很有诱惑力;但是,BeforePost的问题是如何确定调用它的上下文,以便能够判断是否从CheckBrowseMode调用它而不是用户点击它保存按钮。

简单的方法是捕获BeforeAction的{​​{1}}事件,然后再调用数据集上的导航操作,这将触发DBNavigator

.Post

答案 1 :(得分:1)

好的回答MartynA。

如果您不想限制导航器组件并且通常进行此类检查,则可以像这样覆盖TFDQuery.InternalPost:

procedure TFDQuery.InternalPost;
begin
  if State in [dsEdit, dsInsert] then
  begin
    if MessageDlg('Save changes?', mtWarning, [mbYes, mbNo], 0) = mrNo then
      Cancel();
  end;

  inherited;
end;