Recent

Author Topic: How to anchor columns in a TStringGrid?  (Read 5245 times)

edvard

  • Full Member
  • ***
  • Posts: 172
How to anchor columns in a TStringGrid?
« on: April 16, 2015, 07:44:06 am »
Or is it even possible?

I have a TStringGrid that I want to keep only 4 columns: 'Name', 'Start', 'Stop', 'Total'.  I have the TStringGrid component anchored to the bottom and sides of the form, so when the form is resized, the component also.  Trouble is, I want the columns to resize with the form as well, but resizing only shows more rows or columns (or in my case, blank space because there are no more columns).  I don't mind a resize revealing more rows, but the columns I want to follow resizing the form.  Is there such a way?  Or is there a better component for this kind of thing?
Here's what I'm talking about:
All children left unattended will be given a mocha and a puppy.

Arch (though I may go back to Debian)| FreePascal 3.2.2 + Lazarus 2.2.4, GTK2+ and Qt.  Mostly Qt...

munair

  • Hero Member
  • *****
  • Posts: 798
  • compiler developer @SharpBASIC
    • SharpBASIC
Re: How to anchor columns in a TStringGrid?
« Reply #1 on: April 16, 2015, 08:06:24 am »
You should be able to adjust the column widths in the right ratio. Let's say your first column is 70% of total width and the other three 10% each. Then use a matrix to adjust these widths according to the total width.

Let's say total width is 500:

500

70 10 10 10

350 50 50 50

Do the calculation in a procedure and place it in OnResize
« Last Edit: April 16, 2015, 08:13:16 am by Artie »
keep it simple

balazsszekely

  • Guest
Re: How to anchor columns in a TStringGrid?
« Reply #2 on: April 16, 2015, 08:25:59 am »
Usually only one column is resized, but you can implement Artie's idea too.
Code: [Select]
procedure AutoSnapColumn(StringGrid: TStringGrid; const Col: Integer);
var
  I: Integer;
  TotWidth: Integer;
begin
  TotWidth := 0;
  for I := 0 to StringGrid.ColCount - 1 do
  begin
    if I <> Col then
      TotWidth := TotWidth + StringGrid.ColWidths[I];
  end;
  StringGrid.ColWidths[Col] := StringGrid.Width - TotWidth - 5;
end;

procedure TForm1.StringGrid1Resize(Sender: TObject);
begin
  AutoSnapColumn(StringGrid1, 0);
end;

On some widgetset you may need a timer, to prevent freeze. Set timer interval to 100, enabled property to false.
Code: [Select]
procedure TForm1.StringGrid1Resize(Sender: TObject);
begin
  if Timer1.Enabled then
    Exit;
  Timer1.Enabled := True;
end;

procedure TForm1.Timer1Timer(Sender: TObject);
begin
  AutoSnapColumn(StringGrid1, 0);
  Timer1.Enabled := False;
end;

taazz

  • Hero Member
  • *****
  • Posts: 5368
Re: How to anchor columns in a TStringGrid?
« Reply #3 on: April 16, 2015, 09:22:54 am »
I don't think what you are showing can be done automatically you will have to write some code inside the oresize event to size the last column to fill the rest of the area. There is the AutofillColumns property though which will resize all columns to always fill the entire client area, that might actually be enough for your needs.
Good judgement is the result of experience … Experience is the result of bad judgement.

OS : Windows 7 64 bit
Laz: Lazarus 1.4.4 FPC 2.6.4 i386-win32-win32/win64

BitBangerUSA

  • Full Member
  • ***
  • Posts: 183
Re: How to anchor columns in a TStringGrid?
« Reply #4 on: April 16, 2015, 05:11:50 pm »
after a quick check, you *might* find that setting Anchors.akLeft and Anchors.akRight to True and the TStringGrid.Width set from within the OnResize trigger to give you what you want.

for info, i've seen that the column size calcs in the design-time Grid code is a bit odd. for example a grid width of 1000 with 8 columns, the LFM file will have the first 7 column widths at 124 and the 8th at 128. i believe that this is in the base Grid code and haven't attempt to find what versions of Lazarus/FPC are affected...


oops... the reference above to TStringGrid.Width should be the Forms width and the Forms OnResize trigger... i am now fiddling with these things in one of my Projects... your post has lead me to realize a better way to do things.
« Last Edit: April 16, 2015, 07:03:56 pm by BitBangerUSA »
Lazarus Ver 2.2.6 FPC Ver 3.2.2
Windows 10 Pro 64-bit

BitBangerUSA

  • Full Member
  • ***
  • Posts: 183
Re: How to anchor columns in a TStringGrid?
« Reply #5 on: April 16, 2015, 07:43:23 pm »
guess i don't understand what the Grid anchors - top, bottom, left, right - do.
my project doesn't seem to be effected by the settings.

however, it now allows the user to resize the form at will and the grid display automatically sizes all the columns and thus the entire grid. as i set the grid width on the fly in the Form's OnResize, it keeps the grid entirely visible on the form - although the text in cells gets chopped if the column width is too small.

Edit

Apologies - i have code that sizes the Grid Display, which effective makes the Grid Anchors settings have no effect in my Project - effectively doing my own 'anchoring' . IOW, my posting in this thread may just be a distraction, as the OP does want anchoring behavior.

Edit #2

After looking at edvards image and original posting again, it seems i have my program doing exactly what he wants. the key is to set the Grid Width and/or Height in the Forms OnResize Event handler.

Edit #3

taazz is right - and quicker and less wordy than me... i shut up now.
« Last Edit: April 16, 2015, 08:26:40 pm by BitBangerUSA »
Lazarus Ver 2.2.6 FPC Ver 3.2.2
Windows 10 Pro 64-bit

edvard

  • Full Member
  • ***
  • Posts: 172
Re: How to anchor columns in a TStringGrid?
« Reply #6 on: April 17, 2015, 02:23:04 am »
I thought of doing OnResize about 6 minutes (approximately) after posting this, so thanks all for confirming my afterthought, though I was hoping for something a bit more automatic.

Anyways, I only want the Name column to resize, so this should be fairly easy.  Thanks err'body!
All children left unattended will be given a mocha and a puppy.

Arch (though I may go back to Debian)| FreePascal 3.2.2 + Lazarus 2.2.4, GTK2+ and Qt.  Mostly Qt...

edvard

  • Full Member
  • ***
  • Posts: 172
Re: How to anchor columns in a TStringGrid?
« Reply #7 on: April 17, 2015, 07:07:19 am »
EUREKA!
Poking around in TStringGrid in the object inspector, I noticed this:

AutoFillColumns
http://lazarus-ccr.sourceforge.net/docs/lcl/grids/tcustomgrid.autofillcolumns.html
Quote
When this option is turned on, the grid will resize all columns to fill the grid's client width. What columns are resized is determined by the following conditions:

1. Fixed Columns are not resized. 2. If the grid has Custom Columns, all columns with SizePriority=0 are not resized.

Note that Custom Columns are initially created with SizePriority=1. For TDbGrid, which automatically adds Custom Columns, this means the user will not be able to resize such columns using the mouse.

So, I just set 'SizePriority' to 0 for the 'Begin', 'End', and 'Total' columns, but leave SizePriority 1 for the 'Name' column, and ...VOILÀ!!

Now I pull the window edge and only the 'Name' column resizes, awesome!  8)
All children left unattended will be given a mocha and a puppy.

Arch (though I may go back to Debian)| FreePascal 3.2.2 + Lazarus 2.2.4, GTK2+ and Qt.  Mostly Qt...

howardpc

  • Hero Member
  • *****
  • Posts: 4144
Re: How to anchor columns in a TStringGrid?
« Reply #8 on: April 17, 2015, 09:12:30 am »
taazz pointed this out to you (though not with the details) in reply #3

edvard

  • Full Member
  • ***
  • Posts: 172
Re: How to anchor columns in a TStringGrid?
« Reply #9 on: April 18, 2015, 04:39:23 am »
Why so he did.  I think I did try what he suggested, but something wasn't working... like you said, "the details", and I dropped it.  I found it again while clicking EVERY property in the Object Inspector and reading what the mini-help said about it, then I read about the SizePriority setting, and it all went over the waterfall from there. 

Thanks, Taazz... sorry I dropped your suggestion so early, it was actually exactly what I was looking for.
All children left unattended will be given a mocha and a puppy.

Arch (though I may go back to Debian)| FreePascal 3.2.2 + Lazarus 2.2.4, GTK2+ and Qt.  Mostly Qt...

 

TinyPortal © 2005-2018