StringGrid Control

This object allows you to display or collect string data in a grid format. Row 0 and Column 0 are fixed and are generally used for headings. The number of fixed columns and rows can be increased to add more headings. The Fixed Column count must be less than the total column count. The fixed columns and rows cannot be edited when a program is running. You don't have to have fixed columns, but they are useful for headings. 

Significant Properties

Color

Controls the colour of the cells.

ColWidths

Set width of individual column at run-time e.g.

stringgrid1.colwidths[2]:=120;

DefaultRowHeight, DefaultColWidth

Change default row height & column width. Change it at run-time with something like this: 

stringgrid1.defaultcolwidth:=120;

FixedColor

Controls the colour of the fixed cells.

FixedCols

Set this to 1 to get a column of cells for labels.

FixedRow

Set this to 1 to get a row of cells for labels.

Font

Set the font before run-time or change it during execution with e.g.

stringgrid1.font.name:='Courier New';
stringgrid1.cells[0,0]:='Hello';

GridLineWidth

Used to change the width of grid border lines, e.g.

if DrawGrid1.DefaultColWidth > 90 then
  StringGrid1.GridLineWidth := 2
  else
    StringGrid1.GridLineWidth := 1;

Options

GoEditing - set this to true to allow editing of cells.

GoRowSizing, GoColSizing - set these to true to allow re-sizing of columns and rows.

RowCount

Number of rows in grid.

ScrollBars

Whether present.

TabStop

 

TStringGrid.Cells[column,row]

Use this to access the string inside an individual grid cell, to set it, read it or compare it with something else.

TStringGrid.Cols[column], TStringGrid.Rows[row], 

Use this to set all cells in a column.

TStringGrid.RowCount, TStringGrid.ColCount

These can be used to change the number of rows and columns when a program is running.

e.g. stringgrid1.rowcount:=rcount+1;

Example 1: Displaying a Record From a File

We can display a record in a string grid as follows:

procedure TForm1.DisplayButtonClick(Sender: TObject);
var
 person:TPerson;
 personfile:TPersonfile;
 i,j:integer;
begin
 j:=1;
 assignfile(personfile,'persons.dat');
 reset(personfile);
 while not eof(personfile) do
 begin
  i:=1;
  read(personfile,person);
  stringgrid1.cells[i,j]:=person.name;
  inc(i); 
//increment string grid column pointer for next field
  stringgrid1.Cells[i,j]:=person.address;
  inc(i); 
//increment string grid column pointer for next field
  stringgrid1.Cells[i,j]:=datetostr(person.dateofbirth);
  inc(j); 
//increment string grid row pointer for next record
 end;
end;

This will require the declaration of TPerson and TPersonfile in the type section of the Interface section of the unit (as done previously, basically a record structure with name, address and date of birth). The variables person and personfile in the code above could also be declared in the var section of the Form class. When you create this program save it in a new directory and copy the file persons.dat that you made for the earlier program - this should work with the new code, all we have done is add a file open dialog box to access it.

Example 2: A Simple List

In the following example a string grid has been used to provide a way to collect data for a file (from the PostQuickParcels project). 

The data type for the file is simple:

Type Tprice_item=string[5];

The code to set up the string grid is:

procedure TPriceEdit.FormActivate(Sender: TObject);
begin
with stringgrid1 do
 begin
  cells[1,0]:='Price';
  cells[0,0]:='Weight';
  cells[0,1]:=' <2kg.';
  cells[0,2]:=' 2-4kg.';
  cells[0,3]:=' 4-6kg.';
  cells[0,4]:=' 6-8kg.';
  cells[0,5]:=' 8-10kg.';
  cells[0,6]:=' 10-12kg.';
  cells[0,7]:=' 12-14kg.';
  cells[0,8]:=' 14-16kg.';
  cells[0,9]:=' 16-18kg.';
  cells[0,10]:=' 18-20kg.';
  cells[0,11]:=' 20-22kg.';
  cells[0,12]:=' 22-24kg.';
  cells[0,13]:=' 24-26kg.';
  cells[0,14]:=' 26-28kg.';
  cells[0,15]:=' 28-30kg.';
 end;
end;

The code to load the file into the string grid is:

procedure TPriceEdit.LoadButtonClick(Sender: TObject);
var
 price_record:Tprice_item;
 pricefile:file of Tprice_item;
 i:integer;
begin
 assignfile(pricefile,'x:\pricefile.dat');
 reset(pricefile);
 i:=1;
 while not eof (pricefile) do
  begin
   read(pricefile,price_record);
   stringgrid1.Cells[1,i]:=price_record;
   inc(i);
  end;
 closefile(pricefile);
end;

The code to save the contents of the string grid to the file is:

procedure TPriceEdit.SaveButtonClick(Sender: TObject);
var
 price_record:Tprice_item;
 pricefile:file of Tprice_item;
 i:integer;
begin
 assignfile(pricefile,'n:\pricefile.dat');
 reset(pricefile);
 for i:= 1 to 15 do
  begin
   price_record:=StringGrid1.Cells[1,i];
   write (pricefile, price_record);
  end;
 closefile(pricefile);
end;

Example 3 - Structured Data

The principle of choosing a name from a list and displaying an associated data file can be extended to a wide range of situations and applications. The 'Edit Data File' button opens a second form with a string grid to provide a means of entering data into the data file:

Here is the code for loading the data file into the string grid:

procedure TStarsEdit.Button1Click(Sender: TObject);
var
 starrecord:Tstar;
 starfile:file of Tstar;
 i:integer;
begin
 assignfile(starfile,'starfile.dat');
 reset(starfile);
 i:=1;
 while not eof (starfile) do
  begin
   read(starfile,starrecord);
   stringgrid1.Cells[1,i]:=starrecord.name;
   stringgrid1.Cells[2,i]:=starrecord.group_solo;
   stringgrid1.Cells[3,i]:=starrecord.act_type;
   stringgrid1.Cells[4,i]:=starrecord.nationality;
   stringgrid1.Cells[5,i]:=starrecord.datafile;
   inc(i);
  end;
 closefile(starfile);
end;

And here is the code for saving edited data to the data file:

procedure TStarsEdit.Button2Click(Sender: TObject);
var
 starrecord:Tstar;
 starfile:file of Tstar;
 i:integer;
begin
 assignfile(starfile,'starfile.dat');
 reset(starfile);
 for i:= 1 to stringgrid1.RowCount do
  begin
   starrecord.name:=StringGrid1.Cells[1,i];
   starrecord.group_solo:=StringGrid1.Cells[2,i];
   starrecord.act_type:=StringGrid1.Cells[3,i];
   starrecord.nationality:=StringGrid1.Cells[4,i];
   starrecord.datafile:=StringGrid1.Cells[5,i];
   write (starfile, starrecord);
  end;
 closefile(starfile);
end;

The technique of loading names from a file into a ComboBox can be found on the ComboBox page.

Example 4

In this example we see how to fill in a cell in a string grid by clicking on it. This has many possibilities, such as colour-coding a grid according to whether a facility is booked or not. A user would need additional facilities such as changing the colour back to white and changing font colours as well. Changing the colour of cells could also lead to the development of something like the 'Game of Life'.

procedure TForm1.StringGrid1MouseUp(Sender: TObject; Button: TMouseButton;
Shift: TShiftState; X, Y: Integer);
var
 v,w:integer;
 arect:TRect;
begin
 stringgrid1.MouseToCell(X,Y,v,w);
 arect:=stringgrid1.CellRect(v,w);
 stringgrid1.Canvas.Brush.Color:=clred;
 stringgrid1.Canvas.FillRect(arect);
end;

The DefaultDrawing property should be set to True if the colour is to remain after a new cell is clicked.

Example 5

In this example we use the OnMouseUp event of a string grid to set the contents of a cell. This is a fragment from a project on a hotel bookings system. When a cell is clicked the code examines the contents of the cell to see if it is available, in which case the word 'booked' is inserted; if it is already booked the contents will be cleared.

procedure TForm1.StringGrid1MouseUp(Sender: TObject; Button: TMouseButton;
Shift: TShiftState; X, Y: Integer);
var
 Column, Row: Longint;
begin
 StringGrid1.MouseToCell(X, Y, Column, Row);
 if stringgrid1.Cells[Column, Row] = 'Booked' then
  stringgrid1.cells[Column, Row]:= ' '
 else
  stringgrid1.cells[Column, Row]:= 'Booked';
end;

Back to Tutorial

Back to Palette List