Recent

Author Topic: TStringGrid column widths  (Read 8412 times)

wp

  • Hero Member
  • *****
  • Posts: 11923
Re: TStringGrid column widths
« Reply #15 on: April 26, 2022, 10:00:24 pm »
I used Grid.SelectedColor := clSkyBlue.   Did I see a SkyBlue Cell when 'selected' with a mouse-click ? 

Not on your life :(     

I tried with and without the 'useXORFeatures' but without success.
The "magic key" is to set the element goDrawFocusSelected in the grid's Options.

howardpc

  • Hero Member
  • *****
  • Posts: 4144
Re: TStringGrid column widths
« Reply #16 on: April 26, 2022, 10:19:48 pm »
The Options do override each other however.
If you also set goEditing and goAlwaysshowEditor then selection takes the color of the widgetset editor (usually clHighlight I think).

J-G

  • Hero Member
  • *****
  • Posts: 953
Re: TStringGrid column widths
« Reply #17 on: April 26, 2022, 11:31:22 pm »
The "magic key" is to set the element goDrawFocusSelected in the grid's Options.
BINGO!

Thanks WP  -  I'll admit that when I posted this question earlier today, I didn't really think that I would solve the problem without some serious (and complex) coding.

There are just so many 'hidden' facilities within Lazarus and I'm just tinkering at the margins.

Thanks for your extra input as well Howard but it seems that goEditing may restrict the options.

I've now changed to a clMaroon background which (for me) works very well indeed.


FPC 3.0.0 - Lazarus 1.6 &
FPC 3.2.2  - Lazarus 2.2.0 
Win 7 Ult 64

dsiders

  • Hero Member
  • *****
  • Posts: 1084
Re: TStringGrid column widths
« Reply #18 on: April 27, 2022, 12:01:33 am »
The "magic key" is to set the element goDrawFocusSelected in the grid's Options.
BINGO!

Thanks WP  -  I'll admit that when I posted this question earlier today, I didn't really think that I would solve the problem without some serious (and complex) coding.

There are just so many 'hidden' facilities within Lazarus and I'm just tinkering at the margins.

You've exposed another gap in the documentation that needs to be addressed.
Preview Lazarus 3.99 documentation at: https://dsiders.gitlab.io/lazdocsnext

J-G

  • Hero Member
  • *****
  • Posts: 953
Re: TStringGrid column widths
« Reply #19 on: April 27, 2022, 02:33:45 am »
You've exposed another gap in the documentation that needs to be addressed.
Whilst there are genuine 'Hero' members - such as WP & Howard - contributing to this forum, I doubt that there will be much to be gained :)
FPC 3.0.0 - Lazarus 1.6 &
FPC 3.2.2  - Lazarus 2.2.0 
Win 7 Ult 64

J-G

  • Hero Member
  • *****
  • Posts: 953
Re: TStringGrid column widths
« Reply #20 on: April 27, 2022, 01:18:10 pm »
A small - though significant - issue has now reveiled itself after some further testing :(

These Grids would normally be hidden ('Visible' := false) and only shown when the user requests it by clicking on a TButton and hidden again with a second 'click'  -  the Caption is changed at each event to reflect the current state.

This works well, the grid gets populated correctly with data derived from pre-read arrays and column widths & titles are modified/hidden/shown.  At the initial point of display (Grid.Show) no cell has been selected so the aRow & aCol properties are essentially 'undefined'  - - -  I do initialize them to Zero within the procedure 'OnClick' but all my attempts to inhibit the SelectCell from wanting to 'fire' have come to naught.

ie. The data for a Thread (screw - not program!) exists but when the Grid is displayed a new set of figures are calculated and displayed -- before a Grid Cell has been 'clicked'.

I've even tried delaying the 'Grid.Enabled' until after a genuine 'selection' has been made. (Line 16 in the 'Sellect' code fragment and Line 50 in the OnClick fragment)

I'm never sure how much 'code' to provide so that it is useful but not simply confusing but I do know that you cannot advise 'blind' .

This is the 'Select' proc.
Code: Pascal  [Select][+][-]
  1. procedure TForm1.StandardGridSelectCell(Sender: TObject;
  2.                                         aCol, aRow: Integer;
  3.                                         var CanSelect: Boolean);
  4. Var
  5.   R,C     : byte;
  6.   T,P     : single;
  7.  
  8.   procedure ShowStandardName(F,R : byte);
  9.   begin
  10.     [...]
  11.   end;
  12.  
  13. begin
  14.   R := aRow-1;
  15.   C := aCol;
  16.   Err := false;
  17.       StandardGrid.Enabled:=true;                              // moved from OnClick
  18.       If StandardGrid.Cells[C,aRow] = '-' then
  19.         begin
  20.           beep(1200,700);
  21.         end
  22.       else
  23.         begin
  24.           If (C > 1) then
  25.             begin
  26.               Thread.Diam:=StrToFloat(UNIV_Std[R].D) + 0.000001;
  27.               Case Thread.Form of
  28.                 0,7,8 : begin
  29.                           case C of
  30.                             2 : P:=UNIV_Std[R].C;
  31.                             3 : P:=UNIV_Std[R].F;
  32.                             4 : P:=UNIV_Std[R].E;
  33.                           end;
  34.                           if P=0 then
  35.                             begin
  36.                               P := 1;
  37.                               Beep(1200,500);
  38.                               Err := true;
  39.                             end;
  40.  
  41.                           Thread.Pitch:=  Trunc(P * 100 + 0.00001) / 100;      
  42.                           Thread.TPI  := I2M / Thread.Pitch;
  43.                           TPI_Param.Caption :=Trim(Dot(FloatToStr(Thread.TPI/Mil)),6);
  44.                           Pitch_Param.Caption :=Trim(Dot(FloatToStr(Thread.Pitch)),6);
  45.                         end;
  46.                 1,2,
  47.                 4,6   : begin
  48.                             [...]
  49.                          end;
  50.               end;
  51.  
  52.               Calc_and_Show;
  53.               if not Err then
  54.                 ShowStandardName(Thread.Form,C);
  55.             end;
  56.         end;
  57. end;
  58.  

and this is the 'OnClick' code
Code: Pascal  [Select][+][-]
  1. begin
  2. procedure TForm1.ShowStandardClick(Sender: TObject);
  3. Var
  4.   L : byte;
  5.   procedure PopulateMetr;  
  6.      begin
  7.       [...]          
  8.      end;
  9.   procedure PopulateWhit;  
  10.      begin          
  11.      [...]
  12.      end;
  13.    [...]
  14.   procedure SetWidths(a,b,c,d,e : byte);
  15.   begin
  16.     StandardGrid.ColWidths[0]:= a;
  17.     [...]
  18.   end;
  19.  
  20.   if ShowStandard.Caption[1] = 'S' then
  21.     begin
  22.       ShowStandard.Caption := 'Close Standard';
  23.       StandardGrid.Row     := 0;
  24.       StandardGrid.Col     := 0;
  25.       Case Thread.Form of
  26.         0 : begin            // Metric
  27.               L := high(Metr_Std)+1;
  28.               StandardGrid.RowCount := L+1;
  29.               SetWidths(0,40,60,50,0);
  30.  
  31.               StandardGrid.Columns[1].Alignment:=taRightJustify;
  32.  
  33.               StandardGrid.Columns[1].Title.Caption :='Dia. ';
  34.               StandardGrid.Columns[2].Title.Caption :='Coarse';
  35.               StandardGrid.Columns[3].Title.Caption :='Fine';
  36.  
  37.               PopulateMetr;
  38.               StandardGrid.Height      := 5 + (L+1) * StandardGrid.DefaultRowHeight;
  39.             end;
  40.         1 : begin            // Whit
  41.                [...]
  42.             end;
  43.         2 : begin            // Unified
  44.                [...]
  45.             end;
  46.        [...]
  47.         end;
  48.       Close_StdGrid.Left:=1010;
  49.       Close_StdGrid.Show;
  50. //      StandardGrid.Enabled:=true;
  51.       StandardGrid.Show;
  52.     end
  53.   else
  54.     begin
  55.       Std_Entry := 0;
  56.       ShowStandard.Caption := 'Show Standard';
  57.       Form1.Width:=1020;
  58.       StandardGrid.Enabled:=false;
  59.       StandardGrid.Hide;
  60.       Close_StdGrid.Hide;
  61.       Constraints.MaxWidth := 1020;
  62.       Set_Form_Left;
  63.     end;
  64. end;
  65.  

I do hope that I've struck a suitable balance by editing out repetetive (though different) code.

FPC 3.0.0 - Lazarus 1.6 &
FPC 3.2.2  - Lazarus 2.2.0 
Win 7 Ult 64

Josh

  • Hero Member
  • *****
  • Posts: 1274
Re: TStringGrid column widths
« Reply #21 on: April 27, 2022, 01:53:49 pm »
hi

it sounds as though the events are firing when your on mass updating the grid, as they should..

you could try using encapsulating the update grid code with
Code: [Select]
stringgrid1.BeginUpdate;
  ...
  update code for grid
  ....
stringgrid1.EndUpdate;
or create a global variable ie MassGridUpdate:boolean;
and set this to true when your mass updating, and false when finished.

then everywhere you have code that calculates or causes an event to fire do something like
Code: [Select]
if not MassGridUpdate then
begin
  .. code to run for calculations etc
end;
The best way to get accurate information on the forum is to post something wrong and wait for corrections.

J-G

  • Hero Member
  • *****
  • Posts: 953
Re: TStringGrid column widths
« Reply #22 on: April 27, 2022, 02:55:36 pm »
I'm not clear as to what you mean by 'Mass Updating the Grid'.

Before showing the Grid I set Col & Row to 0 and then check to see if Col is greater than 1 (the first 2 columns are never valid selections) before deciding which cell has been selected and therefore can be evaluated for a 'dash' (invalid cell) or does have valid data which deserves a calculation and a new data disply.

What is happening is that the event is 'firing' even though Col & Row are 0.

I wasn't sure whether this was a result of adding the 'Colour the Selected Cell' option but I have now checked   -   and it is!      If I turn off 'goDrawFocusSelected' then the existing display is unaffected when the Grid is displayed  -  which is how it should be.

[ EDIT ]  That last statement is not strictly true !!   
There is some peculiar and apparently 'random' issue. If I simply display the grid, there is no change. Closing and re-opening it also shows no change but if I 'use' the Grid (ie. select a cell) then close it, when I re-open it the display IS affected.

Changing the Thread Form (say, Metric to Whitworth) repeats this result - ie. an untouched Whitworth Grid has no effect even though the Metric Grid has been displayed and 'used' but once the Whitworth Grid has been 'used' then the next showing does affect the main display.    (This is with 'goDrawFocusSelected' set to false)


« Last Edit: April 27, 2022, 03:28:07 pm by J-G »
FPC 3.0.0 - Lazarus 1.6 &
FPC 3.2.2  - Lazarus 2.2.0 
Win 7 Ult 64

J-G

  • Hero Member
  • *****
  • Posts: 953
Re: TStringGrid column widths
« Reply #23 on: April 27, 2022, 07:27:21 pm »
After a great deal of further testing & research, I am no further forward with this problem  :(

First : The Procedure to display the Grid has nothing in it to call the 'OnSelectCell' Event;   though I do set the Grid.Col & Row to zero before  'Grid.Show'.

Surely this should not evoke the 'OnSelectCell' Event ?

Second : By 'stepping through' the OnSelectCell code I find that upon second (and subsequent) activations the aCol parameter is set to the previous value, even though I make a point of making both Col & Row  zero upon 'closing' the Grid.   (I've added this since I posted the code)

I did also try to do so at the end of the OnSelectCell proc but as aCol is not a Var this naturally had no effect.

I've tested with 'goDrawFocusSelected'  both true & false  - they both exhibit the same behaviour so it's not the setting of the Cell colour that is causing the issue, I just didn't notice previously  :-[




FPC 3.0.0 - Lazarus 1.6 &
FPC 3.2.2  - Lazarus 2.2.0 
Win 7 Ult 64

Josh

  • Hero Member
  • *****
  • Posts: 1274
Re: TStringGrid column widths
« Reply #24 on: April 27, 2022, 08:24:58 pm »
Quote
I do set the Grid.Col & Row to zero before  'Grid.Show'

by assigning grid col, or row will cause the event to fire.

quick project that demonstrates this attached.

i assume you have a grid that your populating with various data dependent on other selection,
if you have any cell events then when and during you population of the grid the events will be fired.

i suggest you create a variable massupdate or populatinggrid
and set it to true when your populating the grid with new data, and set it to false when you have completed the population. you may need to call grid.invalidate; ( this will cause events to fire if needed)

then in each grid event you have assigned add as first line
if massupdate then exit;



« Last Edit: April 27, 2022, 08:26:50 pm by josh »
The best way to get accurate information on the forum is to post something wrong and wait for corrections.

J-G

  • Hero Member
  • *****
  • Posts: 953
Re: TStringGrid column widths
« Reply #25 on: April 28, 2022, 12:51:33 am »
Thanks Josh,  Even without your sample project, your statement that "by assigning grid col, or row will cause the event to fire."  'turned the light on'   :D

That hadn't occured to me but is now quite obvious!

We each have a language profile which others may or may not comprehend and your use of 'MassUpdate' just didn't 'fit' with the way I think :)     Your further desription made the concept clear and I tried to use a simple 'UpDating'  but found that is already in use in some unit as an untyped variable so decided upon 'StdUpDating'.

As you surmise, I do re-populate the Grid according to which Thread Form ( of 8 ) is selected but rather than having to set [StdUpDating] for each of them I was able to use it once on & once off before and after a 'Case' statement that selects which 'Form Standard' to populate the Grid with  -  and I didn't need to use grid.invalidate. I didn't think that it would be necesary when 'Closing' the grid but found that without it, the main display was updated with the data from the first cell, thus destroying the selected data. Adding StdUpDating on and off for the Grid Close did solve that though.

This process does handle the inappropriate 'firing' of the OnSelectCell event and the only (very minor) irritation is that when the Grid is initially displayed one cell is shown with the background colour.

The bottom line is that I've learned a great deal about how versatile and complex a TStringGrid is!

« Last Edit: April 28, 2022, 01:06:17 am by J-G »
FPC 3.0.0 - Lazarus 1.6 &
FPC 3.2.2  - Lazarus 2.2.0 
Win 7 Ult 64

J-G

  • Hero Member
  • *****
  • Posts: 953
Re: TStringGrid column widths
« Reply #26 on: May 01, 2022, 11:46:09 am »
Appologies for having to re-visit this thread again but I now need to inhibit selection of the first two columns - ie. so that they do not show the [highlight]  -  doing so is potentially confusing to the user since it has no purpose but looks as though it should.

My thoughts are that using 'Fixed' columns might be the 'key' but although I can set a number of fixed columns in the Object Inspector, they don't appear in the [Editing Grid.Column] so it seems there is no means to 'reference' them.  I must surely be missing something here?

I would also need (on occasion) to set the first 'fixed' column width to zero at run-time.

Alternatively does anyone know a way to inhibit 'highlighting' for specific columns?

FPC 3.0.0 - Lazarus 1.6 &
FPC 3.2.2  - Lazarus 2.2.0 
Win 7 Ult 64

dsiders

  • Hero Member
  • *****
  • Posts: 1084
Re: TStringGrid column widths
« Reply #27 on: May 01, 2022, 05:28:09 pm »
Appologies for having to re-visit this thread again but I now need to inhibit selection of the first two columns - ie. so that they do not show the [highlight]  -  doing so is potentially confusing to the user since it has no purpose but looks as though it should.

My thoughts are that using 'Fixed' columns might be the 'key' but although I can set a number of fixed columns in the Object Inspector, they don't appear in the [Editing Grid.Column] so it seems there is no means to 'reference' them.  I must surely be missing something here?

I would also need (on occasion) to set the first 'fixed' column width to zero at run-time.

Alternatively does anyone know a way to inhibit 'highlighting' for specific columns?

If row selection is enabled in Options, you cannot prevent specific cells from being highlighted. When row selection is not enabled, use OnSelectCell:

Code: Pascal  [Select][+][-]
  1. procedure TForm1.StringGrid1SelectCell(Sender: TObject; aCol, aRow: Integer; var CanSelect: Boolean);
  2. begin
  3.   if (aCol =  1) then CanSelect := False;
  4. end;
  5.  

To show or hide the indicator column, set the column width:

Code: Pascal  [Select][+][-]
  1. // hide it
  2. StringGrid1.ColWidths[0] := 0;
  3. // show it
  4. StringGrid1.ColWidths[0] := 42;
  5.  

Preview Lazarus 3.99 documentation at: https://dsiders.gitlab.io/lazdocsnext

J-G

  • Hero Member
  • *****
  • Posts: 953
Re: TStringGrid column widths
« Reply #28 on: May 01, 2022, 09:39:34 pm »
Thanks for your responce @dsiders,
I do use OnSelectCell and show or hide Columns by making the width = 0.

I hadn't picked up the fact that CanSelect is a Var so can be manipulated 'after the event' as it were.
However - I've tried :
Code: Pascal  [Select][+][-]
  1.  if (aCol < 2) then
  2.     CanSelect := false;
as well as :
Code: Pascal  [Select][+][-]
  1. if (aCol=0) or (aCol=1) then
  2.     CanSelect := false;
and both cause an exception class 'External: SIGSEGV'

Which in turn results in a line in the Assembler window headed
'fpc_shortstr_to_ansistr (27)' 
"movzbl  (%esi),%edx"   

which is way beyond my understanding :)

« Last Edit: May 01, 2022, 09:41:06 pm by J-G »
FPC 3.0.0 - Lazarus 1.6 &
FPC 3.2.2  - Lazarus 2.2.0 
Win 7 Ult 64

dsiders

  • Hero Member
  • *****
  • Posts: 1084
Re: TStringGrid column widths
« Reply #29 on: May 01, 2022, 09:47:19 pm »
Thanks for your responce @dsiders,
I do use OnSelectCell and show or hide Columns by making the width = 0.

I hadn't picked up the fact that CanSelect is a Var so can be manipulated 'after the event' as it were.
However - I've tried :
Code: Pascal  [Select][+][-]
  1.  if (aCol < 2) then
  2.     CanSelect := false;
as well as :
Code: Pascal  [Select][+][-]
  1. if (aCol=0) or (aCol=1) then
  2.     CanSelect := false;
and both cause an exception class 'External: SIGSEGV'

Which in turn results in a line in the Assembler window headed
'fpc_shortstr_to_ansistr (27)' 
"movzbl  (%esi),%edx"   

which is way beyond my understanding :)

It may be that the older version of Lazarus you're using does not match the current implementation. grids.pp was refactored at some point in the past.

You could try a more recent Lazarus version.

The attached simple demo works for 2.2.0 and 2.3.0.

« Last Edit: May 01, 2022, 09:57:40 pm by dsiders »
Preview Lazarus 3.99 documentation at: https://dsiders.gitlab.io/lazdocsnext

 

TinyPortal © 2005-2018