Forum > Databases

[SOLVED] DBGrid - Center selected row.

(1/3) > >>

pcurtis:
I have a DBGrid that can show 7 rows. The dataset has 1000 rows.

How can I center the selected row in the center of the grid?
(If RecNo > 3 and RecNo < 997)

Zvoni:
Maybe with some math using TopRow-Property?
along the lines of
Grid.TopRow:=IndexOfSelectedRow - 3

You would have to catch the Edge-cases of course (SelectedRow Index is 2, 2-3 is -1, setting TopRow to -1 = KABOOM)

Nota Bene: No idea if my proposal works, since i have no clue to how TopRow works, but it was the one Property catching my eye

pcurtis:
TopRow is not a property of TDBGrid

or after a


--- Code: Pascal  [+][-]window.onload = function(){var x1 = document.getElementById("main_content_section"); if (x1) { var x = document.getElementsByClassName("geshi");for (var i = 0; i < x.length; i++) { x[i].style.maxHeight='none'; x[i].style.height = Math.min(x[i].clientHeight+15,306)+'px'; x[i].style.resize = "vertical";}};} ---  iTemp := ZQuery1['fnIDX'];   MyQuery.ExecSQL; // update recordset  ZQuery1.Close;  ZQuery1.Open;  ZQuery1.Locate('fnIDX', iTemp, []); 
put the DBGrid back to the same place / position as before the update.

Zvoni:

--- Quote from: pcurtis on November 24, 2021, 11:27:18 am ---TopRow is not a property of TDBGrid

--- End quote ---
Argg... missed that.
It's protected in TCustomGrid.
No idea how to make a protected Property in Ancestor to public in the Grandkid

Handoko:
If you meant you want the DBGrid to scroll to certain position showing certain record number, then this maybe is what you want:


--- Code: Pascal  [+][-]window.onload = function(){var x1 = document.getElementById("main_content_section"); if (x1) { var x = document.getElementsByClassName("geshi");for (var i = 0; i < x.length; i++) { x[i].style.maxHeight='none'; x[i].style.height = Math.min(x[i].clientHeight+15,306)+'px'; x[i].style.resize = "vertical";}};} ---unit Unit1; {$mode objfpc}{$H+} interface uses  Classes, SysUtils, dbf, Forms, Controls, Dialogs, DBGrids, StdCtrls, Spin, DB; type   { TForm1 }   TForm1 = class(TForm)    Button1: TButton;    Dbf1: TDbf;    DBGrid1: TDBGrid;    Label1: TLabel;    speGoto: TSpinEdit;    speTop: TSpinEdit;    procedure Button1Click(Sender: TObject);    procedure FormCreate(Sender: TObject);  private    function  RandomChars(Count: Integer): string;    procedure GenerateDataFile;    procedure GotoRow(RowNo, TopPadding: Integer);  end; var  Form1: TForm1; implementation Const  DataFileName = 'Data.dbf'; {$R *.lfm} { TForm1 } procedure TForm1.FormCreate(Sender: TObject);var  aDataSource: TDataSource;begin   // Connection and data  aDataSource         := TDataSource.Create(Self);  aDataSource.DataSet := Dbf1;  Dbf1.FilePathFull   := ExtractFileDir(ParamStr(0));  Dbf1.TableName      := DataFileName;  if not(FileExists(DataFileName)) then    GenerateDataFile;  Dbf1.Active        := True;  DBGrid1.DataSource := aDataSource;   // Appearance  Constraints.MinHeight := 240;  Constraints.MinWidth  := 320;  DBGrid1.Anchors       := [akLeft, akRight, akTop, akBottom];  Button1.Anchors       := [akLeft, akBottom];  speGoto.MaxValue      := Dbf1.ExactRecordCount;  speGoto.Anchors       := [akLeft, akBottom];  speTop.MaxValue       := Dbf1.ExactRecordCount;  speTop.Anchors        := [akLeft, akBottom]; end; procedure TForm1.Button1Click(Sender: TObject);begin  GotoRow(speGoto.Value, speTop.Value);end; function TForm1.RandomChars(Count: Integer): string;var  S: string;  i: Integer;begin  if Count < 1  then Count := 1;  if Count > 20 then Count := 20;  S := '';  for i := 1 to Count do    S := S + chr(Ord('a')+Random(26));  Result := S;end; procedure TForm1.GenerateDataFile;const  TotalItems = 1000;var  i: Integer;begin  with Dbf1 do  begin    FieldDefs.Add('ID', ftInteger, 0, True);    FieldDefs.Add('DATA', ftString, 8, True);    CreateTable;    Open;      for i := 1 to TotalItems do      begin        Append;        FieldByName('ID').AsInteger  := i;        FieldByName('DATA').AsString := RandomChars(8);        Post;      end;    Close;  end;end; procedure TForm1.GotoRow(RowNo, TopPadding: Integer);var  Total:       Integer;  VisibleRows: Integer;  Key:         Word;  Adjust:      Integer;  i:           Integer;begin   Total := Dbf1.ExactRecordCount;  if Total <= 0 then Exit;   // Get visible row count  VisibleRows := 0;  for i := 1 to Total do    if DBGrid1.IsCellVisible(1, i) then      Inc(VisibleRows);  if VisibleRows <= 0 then Exit;   // Send Ctrl+Home keyboard signal to the grid  Key := 36;  DBGrid1.EditorKeyDown(Self, Key, [ssCtrl]);   // Send Arrow_Down keyboard signal to the grid  for i := 1 to RowNo-1 do  begin    Key := 40;    DBGrid1.EditorKeyDown(Self, Key, []);  end;   // Send arrow up and down signals to get position for the top padding  if TopPadding >= VisibleRows + 1 then Exit;  Adjust := VisibleRows - TopPadding - 1;  if RowNo + Adjust > Total then    Adjust := Total - RowNo;  for i := 1 to Adjust do  begin    Key := 40;    DBGrid1.EditorKeyDown(Self, Key, []);  end;  for i := 1 to Adjust do  begin    Key := 38;    DBGrid1.EditorKeyDown(Self, Key, []);  end; end; end.

* First time running the program, a dbf with 1000 records will be created, see line #86
* The grid will try to scroll to position the RecNo to have the top padding as the value provided but it may fail on some cases
* TopPadding = 0 means to show the wanted RecNo on the first row in the grid
* The trick to make the grid to scroll automatically is in the GotoRow procedure, see line #109Warning:
Tested on Lazarus 2.0.10 GTK2 Linux, it may or may not work on future versions of Lazarus and it is may not work on other OSes.

Navigation

[0] Message Index

[#] Next page

Go to full version