Recent

Author Topic: [SOLVED] TStringGrid.VisibleColCount ... how does it really work?  (Read 668 times)

EganSolo

  • Sr. Member
  • ****
  • Posts: 334
Here's the code of TCustomGrid.GetVisibleColCount

Code: Pascal  [Select][+][-]
  1. function TCustomGrid.GetVisibleColCount: Integer;
  2. begin
  3.   with FGCache do begin
  4.     Result := VisibleGrid.Right-VisibleGrid.Left;
  5.     if GridWidth<=ClientWidth then
  6.       inc(Result)
  7.   end;
  8. end;
  9.  

Could someone please explain how this method retrieves the number of visible columns? In case you're wondering, FGCache is a record holding a TRect called VisibleGrid and this method returns the difference between its left and right ... how does one derive the number of visible columns out of that?
« Last Edit: June 15, 2025, 10:30:40 am by EganSolo »

jamie

  • Hero Member
  • *****
  • Posts: 6995
Re: TStringGrid.VisibleColCount ... how does it really work?
« Reply #1 on: June 12, 2025, 11:41:43 am »
The inc result is accounting for patially visible cells
The only true wisdom is knowing you know nothing

wp

  • Hero Member
  • *****
  • Posts: 12910
Re: TStringGrid.VisibleColCount ... how does it really work?
« Reply #2 on: June 12, 2025, 12:04:41 pm »
The property VisibleColCount does not apply to columns which are hidden by turning their Visible property off. According to Delphi documentation (https://docwiki.embarcadero.com/Libraries/Sydney/en/Vcl.Grids.TCustomGrid.VisibleColCount), it is the number of fully visible, scrollable columns. In Lazarus basically it is the same, but gets more complicated because in contrast to Delphi we have the goSmoothScroll option. And the consequence is that when the grid is scrolled to the right the left-most columns may be partially visible - but Lazarus counts this as "fully visible" ...

Play with attached demo project to see how it works. The rules are (according to my experiments):

- The fixed columns and fully out-of-view columns are not counted in VisibleColCount.
- Partially visible columns at the right are not counted.
- Partially visible columns at the left ARE counted.
- Columns having Visible=false ARE counted

Really quite confusing, I agree...

Looking at it from the viewpoint of the GCache.VisibleGrid appears more logical to me: It includes all partially and fully visible columns, except for the fixed column(s) (and "hidden" columns).

The number of visible columns then would be
Code: Pascal  [Select][+][-]
  1. type
  2.   TMyStringGrid = class(TStringGrid);
  3.  
  4. function GetPartiallyVisibleCols(AGrid: TStringGrid): Integer;
  5. var
  6.   xLeft: Integer;
  7.   xRight: Integer;
  8.   c, c1, c2: Integer;
  9. begin
  10.   if AGrid.FixedCols > 0 then
  11.     xLeft := AGrid.CellRect(AGrid.FixedCols-1, 0).Right
  12.   else
  13.     xLeft :=0;
  14.   xRight := AGrid.ClientRect.Right;
  15.  
  16.   Result := 0;
  17.   with TMyStringGrid(AGrid) do
  18.   begin
  19.     c1 := GCache.VisibleGrid.Left;
  20.     c2 := GCache.VisibleGrid.Right;
  21.   end;
  22.   for c := c1 to c2 do begin
  23.     if AGrid.CellRect(c, 0).Left < xLeft then
  24.       inc(Result)
  25.     else
  26.     if AGrid.CellRect(c, 0).Right > xRight then
  27.       inc(Result);
  28.   end;
  29. end;
  30.  
  31. function GetFullyOrPartiallyVisibleCols(AGrid: TStringGrid): Integer;
  32. begin
  33.   with TMyStringGrid(AGrid) do
  34.     Result := GCache.VisibleGrid.Right - GCache.VisibleGrid.Left + 1;
  35. end;
  36.  
  37. function GetFullyVisibleCols(AGrid: TStringGrid): Integer;
  38. begin
  39.   Result := GetFullyOrPartiallyVisibleCols(AGrid) - GetPartiallyVisibleCols(AGrid);
  40. end;

« Last Edit: June 12, 2025, 01:43:53 pm by wp »

EganSolo

  • Sr. Member
  • ****
  • Posts: 334
Re: TStringGrid.VisibleColCount ... how does it really work?
« Reply #3 on: June 13, 2025, 09:55:30 am »
Whoa! Thanks wp for your amazing answer and the demo! Truly appreciate it. I ran the attached demo and it helped. Thanks.

My confusion stems from the following simple example I created after I saw your demo:
  • I dropped a string grid on a form and created three columns. The first and second have their Visible property set to false, and the third has its Visible property set to True.
  • I set AutoFillColumns to True.
  • There's one fixed row and zero fixed columns.
  • RowCount = 2
  • I added a button which sets Cells[2,1] to the value of VisibleColCount

As you can see from the attached picture, the value is 3. It tells me there are three visible columns.
Reading back what you wrote, this is the number of fully visible, scrollable columns. But columns 0 and 1 are neither visible nor scrollable ... Columns 0 and 1 are fully out-of-view, are they not? If so, shouldn't VisibleColCount report back 1 instead of 3?

Should I interpret VisibleColCount to mean "Potentially visible and scrollable"? Does that mean it's the same as the total number of columns minus the fixed ones?

Sorry if I'm rambling, but this is confusing me.




wp

  • Hero Member
  • *****
  • Posts: 12910
Re: TStringGrid.VisibleColCount ... how does it really work?
« Reply #4 on: June 13, 2025, 10:57:24 am »
VisibleColCount exists for reasons of Delphi compatibility. But Delphi does not support the Columns collection which is available in the LCL. Therefore, VisibleColCount ignores the fact that a column can be switched to invisible, and as a consequence the first and second columns are counted by this function although their Visible property is false.

EganSolo

  • Sr. Member
  • ****
  • Posts: 334
Re: TStringGrid.VisibleColCount ... how does it really work?
« Reply #5 on: June 15, 2025, 10:30:20 am »
Got it! That makes sense! I haven't used Delphi for so long that I had forgotten that the column collection is an LCL-specific feature. Thanks wp!

 

TinyPortal © 2005-2018