I have a FDQuery bound to a FDConnection.
I am displaying the data on my form with DB Data-Aware components.
Whenever i use the FPQuery.Next, .Prior, ... it browses between the results.
Everything is working fine.
Except when i change a value (e.g. John -> Jane) and then use FPQuery.Next to get the next result it saves commits the changed value to the db even tho i didn't FDQuery1.CommitUpdates.
Is there a way to only save changed DataFields when the user presses the nbPost-Button or uses FDQuery1.CommitUpdates and NOT when browsing between results?
Thanks!
Like I said in a comment, the standard TDataset
behaviour is to call its .Post
method to save changes to the current row before navigating to another one. This happens in the routine TDataSet.CheckBrowseMode
in Data.DB.Pas
, which is called before any navigation action. This can't be changed without deriving a custom TDataset
descendant.
(from 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;
Of course, a TDataSet
has a BeforePost
event, so it might be tempting to try and use that to cancel changes; however, the problem with BeforePost
is how to determine the context in which it is being called, so as to be able to tell whether its being called from CheckBrowseMode
rather than as a result of the user clicking the Save button.
The simple way around that is to catch the BeforeAction
event of your DBNavigator
, before it calls a navigation action on the dataset which will trigger the .Post
:
procedure TForm1.DBNavigator1BeforeAction(Sender: TObject; Button:
TNavigateBtn);
var
Res : Integer;
DataSet : TDataSet;
begin
DataSet := DBNavigator1.DataSource.DataSet;
case Button of
nbFirst,
nbPrior,
nbNext,
nbLast: begin
if DataSet.State in [dsEdit, dsInsert] then begin
Res := MessageDlg('The current row has unsaved changes. Abandon them?', mtWarning, [mbYes, mbNo], 0);
if Res = mrYes then
DataSet.Cancel
else
DataSet.Post;
end;
end;
end;
end;