Forum > LCL

[SOLVED] TStringGrid.Columns.Count=0 after TStringGrid.LoadFromCSVStream

(1/2) > >>

Vodnik:
I'm trying to hide a column of TStringGrid.
If TStringGrid is created at design time, there is no problem:

--- 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";}};} ---StringGrid1.Columns[2].Visible:=False;But when grid content is loaded at runtime:

--- 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";}};} ---StringGrid1.LoadFromCSVStream(SS,',',true,0,true);the same string causes "out of bounds" error.
Well, grid is displayed fine, but StringGrid1.Columns.Count is 0.
Test project is attached. What I'm doing wrong?
 

wp:
The Lazarus StringGrid can work with columns, unlike Delphi, and your code seems to do that because you access the column with index 2. However, this is not the default mode - normally TStringGrid has no column classes, and you must explicitely add Columns to activate this mode.

When you load data from a csv file into an empty grid it basically is not clear whether columns should be created or not. The grid does a simple check to make a decision: If there is at least one column it will read the files into a "column-aware" grid, otherwise into a normal grid.

So, all you have to do is to create one column before calling LoadCSVFile. Then this method will create the other columns automatically:

--- 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";}};} ---procedure TForm1.FormCreate(Sender: TObject);var SS: TStringStream;     I: Integer;begin  SS:=TStringStream.Create;  SS.LoadFromFile('StringGrid.csv');  with TStringGrid.Create(Form1) do begin    Parent:=Form1;    ...    Columns.Add;              // <--- ADDED    LoadFromCSVStream(SS,',',true,0,true);    ...  end;  SS.Free;end;

Vodnik:
Thank you for the explanation, @wp!
This is a non-evident trick for me.

wp:

--- Quote from: Vodnik on December 03, 2023, 10:45:52 pm ---Thank you for the explanation, @wp!
This is a non-evident trick for me.

--- End quote ---
I did not know it either. Let me show you how I found out: I added a custom option "-gw3" (without quotes) to "Additions and overrides" in the project options which allows me to debug into LCL and third-party units. With the debugger, I stepped into LoadFromCSVStream, and saw in the nested function NewRecord a call to Columns.Add which confirms that LoadFromCSVStream, in fact, is able to add columns. But there is an "if Columns.Enabled" before that. A Ctrl-Click on this "Enabled" leads to the TGridColumns property Enabled. It does not have a setter function and thus cannot be activated immediately. But the property getter function "GetEnabled" (another Ctrl+Click) tells that Enabled is true when another property, VisibleCount, is true. And the getter of VisibleCount simple returns the Count of the Columns collection. Then it was clear: Add a column to make Columns.Count <> 0.

Added a note to the grids wiki page: https://wiki.freepascal.org/Grids_Reference_Page#procedure_LoadFromCSVFile.28AFileName:_string.3B_ADelimiter:Char.3D.27.2C.27.3B_WithHeader:boolean.3Dtrue.29.3B

dsiders:

--- Quote from: wp on December 03, 2023, 11:37:00 pm ---
--- Quote from: Vodnik on December 03, 2023, 10:45:52 pm ---Thank you for the explanation, @wp!
This is a non-evident trick for me.

--- End quote ---
I did not know it either. Let me show you how I found out: I added a custom option "-gw3" (without quotes) to "Additions and overrides" in the project options which allows me to debug into LCL and third-party units. With the debugger, I stepped into LoadFromCSVStream, and saw in the nested function NewRecord a call to Columns.Add which confirms that LoadFromCSVStream, in fact, is able to add columns. But there is an "if Columns.Enabled" before that. A Ctrl-Click on this "Enabled" leads to the TGridColumns property Enabled. It does not have a setter function and thus cannot be activated immediately. But the property getter function "GetEnabled" (another Ctrl+Click) tells that Enabled is true when another property, VisibleCount, is true. And the getter of VisibleCount simple returns the Count of the Columns collection. Then it was clear: Add a column to make Columns.Count <> 0.

Added a note to the grids wiki page: https://wiki.freepascal.org/Grids_Reference_Page#procedure_LoadFromCSVFile.28AFileName:_string.3B_ADelimiter:Char.3D.27.2C.27.3B_WithHeader:boolean.3Dtrue.29.3B

--- End quote ---

It is documented at https://lazarus-ccr.sourceforge.io/docs/lcl/grids/tcustomstringgrid.loadfromcsvstream.html, but I'm always open to ways topics can be improved.

Navigation

[0] Message Index

[#] Next page

Go to full version