Recent

Author Topic: [Solved] save dbgrid columns position  (Read 4776 times)

Hansvb

  • Hero Member
  • *****
  • Posts: 825
[Solved] save dbgrid columns position
« on: February 27, 2015, 05:02:37 pm »
I want to save the dbgrid columns position when a column is moved in the dbgrid.
When i set my code in the OnColumMoved then nothing happens.
When i set my code in the OnDrawColumnCell it works. But i do not want to exceute the procedure after every OnDrawClolumnCell. Only after a column is really moved.

What is the best location?

« Last Edit: June 22, 2025, 11:29:05 am by Hansvb »

howardpc

  • Hero Member
  • *****
  • Posts: 4144
Re: save dbgrid columns position
« Reply #1 on: February 27, 2015, 06:10:03 pm »
The following event handler saves correct information for me. I'm sure you can adapt it for your use.
Code: [Select]
procedure TForm1.DBGridColumnMoved(Sender: TObject; FromIndex, ToIndex: Integer);
var
  col0: integer;
  dbg: TDBGrid;
  sl: TStringList;
const
  logfileName = 'log.txt';
begin
  if not (Sender is TDBGrid) then Exit;
  dbg:=TDBGrid(Sender);
  if (dgIndicator in dbg.Options) then
    col0:=1
  else
    col0:=0;
  sl:=TStringList.Create;
  try
    sl.Append(Format('Column %s moved from index %d to index %d',
       [dbg.Columns[FromIndex-col0].Title.Caption, FromIndex, ToIndex]));
    sl.SaveToFile(logfileName);
  finally
    sl.Free;
  end;
end;

Hansvb

  • Hero Member
  • *****
  • Posts: 825
Re: save dbgrid columns position
« Reply #2 on: March 03, 2015, 04:58:50 pm »
My code works fine but the on colum move seems te react after the second move and not after the first move.
When i move a colum then my txt file has a new timestamp but i see the original columorder and not the changed one. When i move the column again the order in my txt file is changed and good.

Code: [Select]
procedure TFrm_main.DBGrid_ModelColumnMoved(Sender: TObject;
  FromIndex, ToIndex: Integer);
begin
    DBGridvisueel.saveGridLayout(DBGrid_Model, Frm_Main.LastQuery_Model,
                                 ApplicatiePad + '\Settings\'
                                               + UserName_PC + '_'
                                               +  'Model.txt');
end; 

procedure TDBGrid_visueel.saveGridLayout(Mydbgrid: TDBGrid; Query : Integer; fileName: string);
var
  lines: TStringList;
  i: integer;
begin
  if Query = 604 then
    begin
      try
        lines := TStringList.Create;
        with Mydbgrid do
        begin
          for i := 0 to Mydbgrid.Columns.count-1 do
            begin
        lines.Add
              (IntToStr(Mydbgrid.Columns[i].Index)
          + '~ ' + Mydbgrid.Columns[i].DisplayName
          + '~ ' + Mydbgrid.Columns[i].Title.Caption
          + '~ ' + IntToStr(Mydbgrid.Columns[i].Width)
              );
      end;
        end;
        lines.SaveToFile(fileName);
      finally
        lines.free;
      end;
    end;
end;

howardpc

  • Hero Member
  • *****
  • Posts: 4144
Re: save dbgrid columns position
« Reply #3 on: March 03, 2015, 05:46:23 pm »
Perhaps you need to record the ToIndex parameter value in your log, rather than the Columns.Index value (which may not yet have been updated).

Hansvb

  • Hero Member
  • *****
  • Posts: 825
Re: save dbgrid columns position
« Reply #4 on: March 03, 2015, 08:50:31 pm »
i can't find a toindex parameter

howardpc

  • Hero Member
  • *****
  • Posts: 4144
Re: save dbgrid columns position
« Reply #5 on: March 03, 2015, 11:17:11 pm »
Sorry, I mislead you.
Try this. Add a procedure to Tfm_main

Code: [Select]
procedure DoSave(Data: PtrInt);

and implement it as
Code: [Select]
procedure TFrm_main.DoSave(Data: PtrInt);
begin
  DBGridvisueel.saveGridLayout(DBGrid_Model, Frm_Main.LastQuery_Model,
                                 ApplicatiePad + '\Settings\'
                                               + UserName_PC + '_'
                                               +  'Model.txt');
end;

Then change the OnColMoved event handler to
Code: [Select]
procedure TFrm_main.DBGrid_ModelColumnMoved(Sender: TObject;
  FromIndex, ToIndex: Integer);
begin
  Application.QueueAsyncCall(@DoSave, 0);
end; 

Leave
Code: [Select]
procedure TDBGrid_visueel.saveGridLayout(...) unchanged

I think that will give time for the new column data to be updated correctly before it is read by the saving code.

Hansvb

  • Hero Member
  • *****
  • Posts: 825
Re: save dbgrid columns position
« Reply #6 on: March 04, 2015, 04:59:53 pm »
Thanks,  that works great!

I have some reading to do for the "QueueAsyncCall"  :)

Hansvb

  • Hero Member
  • *****
  • Posts: 825
Re: save dbgrid columns position
« Reply #7 on: June 22, 2025, 11:28:50 am »
10 years later I have exactly the same question. How do I save the dbgrid column positions and how do I read them again. The first Google result turns out to be a post of myself that is already 10 years old. What howardpc gives to this still works. How cool is that.  :)  I see that I never have completed the question. Reading the positoins goes as follows (also 10 year old code, I have forgotten a lot I notice  :-[).

Code: Pascal  [Select][+][-]
  1. procedure loadGridLayout(Mydbgrid: TDBGrid; fileName: string);
  2. var
  3.   lines: TStringList;
  4.   columnInfo: TStringList;
  5.   lineCtr: integer;
  6.   colIdx: integer;
  7.   cnt: integer;
  8. begin
  9.   try
  10.     lines := TStringList.Create;
  11.     columnInfo := TStringList.Create;
  12.     lines.LoadFromFile(fileName);
  13.     for lineCtr := 0 to lines.Count-1 do
  14.       begin
  15.         if trim(lines[lineCtr]) <> '' then
  16.           begin
  17.             StringExplode(lines[lineCtr], '~ ', columnInfo);
  18.             cnt:=Mydbgrid.Columns.count;
  19.             // go through all the columns, looking for the one we are currently working on
  20.             for colIdx := 0 to cnt-1 do
  21.               begin
  22.                 // once found, set its width and title, then its index (order)
  23.                 if Mydbgrid.Columns[colIdx].FieldName = columnInfo[1] then
  24.                   begin
  25.                     Mydbgrid.Columns[colIdx].Width := StrToInt(columnInfo[3]);
  26.                     Mydbgrid.Columns[colIdx].Title.Caption := columnInfo[2];
  27.  
  28.                     // do the index assignment last!
  29.                     // ignore the index specified in the file. use its line
  30.                     Mydbgrid.Columns[colIdx].Index := lineCtr; //StrToInt(columnInfo[0]); order instead
  31.                   end; // if
  32.               end;
  33.         end;
  34.       end;
  35.   finally
  36.     lines.free;
  37.     if assigned(columnInfo) then
  38.       columnInfo.free;
  39.   end;
  40. end;
  41.  
  42. procedure StringExplode(s: string; Delimiter: string;
  43.   var res: TStringList);
  44. begin
  45.   res.Clear;
  46.   res.Text := StringReplace(s, Delimiter, #13#10, [rfIgnoreCase, rfReplaceAll]);
  47. end;
  48.  

 

TinyPortal © 2005-2018