views:

239

answers:

2

In my application, there are these data components linked like so:

DBGrid > (DataSource > ADOQuery > ADOConnection)
DBNavigator > (DataSource > ADOQuery > ADOConnection)

Whenever the user selects a different row from the DBGrid, or uses the DBNavigator, the ADOQuery's current record changes. Fine, but when the user makes some changes to the current record, then navigating away from it, the changes made are lost.

I would like to display a confirmation dialogue where the user would need to confirm navigating away from the current record in case there were any changes made. And, when the user clicks 'No' then I would like the application NOT to change the current record.

Where should I insert the code? Which event is it that is fired before user navigates away from the current record and how do I stop the action from continuing?

if anythingChanged then
  if messageDlg(...)=mrNo then
    ADOQuery.dontChangeCurrentRecord;
+3  A: 

Put a conditional Abort on 'BeforeScroll';

procedure TForm1.ADOQuery1BeforeScroll(DataSet: TDataSet);
begin
  if TAdoQuery(DataSet).Modified then  //if anythingChanged then
    Abort;
end;
Sertac Akyuz
WOO-HOO! During the 33 minutes I waited for this answer, I managed to find out that it's the BeforeScroll event I need to fiddle with, but I did not know about the silent abort trick :-$ THANKS A LOT!
Peter Perháč
Note that BeforeScroll does not cover all situations (like someone closing the dataset, or just refreshing the dataset). I once wrote a TRecordArrivedNotifier (based on a TDataLinkReflector) that fires an event when you arrive on a new record. You could use that as a base to fire the "Abort". See my talk "Smarter code with databases and data aware controls" here: http://wiert.wordpress.com/conferences-seminars-and-other-public-appearances/
Jeroen Pluimers
+1  A: 

Strange. What sort of grid are you using that doesn't automatically call Post in this situation?

If you want to do something like this, probably the best place to put the event handler, if the grid doesn't provide a convenient event for it, is on the dataset's BeforeScroll event. To keep the changes from being applied, you can call Abort.

Mason Wheeler
the changes are not made in the grid. the grid is read-only but the rest of the screen refreshes based on the currently selected record. My problem is solved now, thanks to Sertac Akyuz. Your solution is practically identical. Thanks too.
Peter Perháč