Title: How to Refresh a DBGrid without Losing the Current Row Position
There's DBGrid, there's a dataset and we have a data aware Delphi application :)
When DBGrid is used to display data from a dataset (query or table), by design, after you call Refresh method on a dataset (re-open) (for example, using a DBNavigator), the current row position will be set to zero (first record).
This means that if a user has selected a row somewhere near the bottom of a DBGrid, after a Refresh, the active row will be changed to first row :(
If you have been asking "Is there any way to reopen or refresh a query, leaving the TDBGrid data exactly where it is (without changing the positions)?" Here's one answer to the problem:
Refresh DBGrid Data - Preserve Row Position
Here's a handly little procedure to refresh the content of a DBGrid without losing the row position.
//THackDBGrid = class(TDBGrid)
//refresh datagrid data - preserve row position
procedure Refresh_PreservePosition;
var
rowDelta: Integer;
row: integer;
recNo: integer;
ds : TDataSet;
begin
ds := THackDBGrid(DBGrid1).DataSource.DataSet;
rowDelta := -1 + THackDBGrid(DBGrid1).Row;
row := ds.RecNo;
ds.Refresh;
with ds do
begin
DisableControls;
RecNo := row;
MoveBy(-rowDelta) ;
MoveBy(rowDelta) ;
EnableControls;
end;
end;
Note the protected hack used here (THackDBGrid) to get the hidden (protected) Row property!