TAdvStringGrid

Example 14 : Showing the grouping functions in TAdvStringGrid

vcl grid grouping

TAdvStringGrid v1.83 has built in single level automatic grouping and grouped sorting. This makes it easy to add grouping features with a few lines of code. In this example application, it was choosen to trigger the grouping by right-clicking on the column header and trigger the sorting with the left click (as default when the SortShow property is true)

As an introduction, this is an overview of the grouping methods :

procedure Group(ColIndex:integer);
procedure UnGroup;
property GroupColumn:integer;

The Group method groups based on the column ColIndex. It automatically adds the expand / contract nodes. When expand / contract nodes are available, the normal sort when a column header is clicked changes to inter group sorting. The Group method is equivalent to assignment of the GroupColumn property, ie :

AdvStringGrid.Group(5) has the same effect as AdvStringGrid.GroupColumn:=5;

Note that the column for grouping can only start from column 1, since column 0 is the placeholder for the expand / contract nodes. The GroupColumn property has the additional benefit that it returns -1 when grouping is not active. Otherwise it returns the current grouped column.

To undo the effect of grouping, the UnGroup method can be used, or as an alternative, the GroupColumn property can be set to -1.

Back to the example application, to start, some data is loaded into the grid from a CSV file and a column is added for the positioning of the grouping expand / contract nodes. This is done in the formcreate handler :

advstringgrid1.savefixedcells:=false;
advstringgrid1.loadfromcsv('cars.csv');
advstringgrid1.autosizecolumns(false,10);
advstringgrid1.insertcols(0,1);
advstringgrid1.colwidths[0]:=20;

The next step, is to write the event handler to set the grouping when a column header is right clicked.

procedure TForm1.AdvStringGrid1RightClickCell(Sender: TObject; Arow,Acol: Integer);
begin
with AdvStringGrid1 do
  if (arow=0) then
   begin
    label3.caption:=cells[acol,0];
    if (GroupColumn<>-1) and (acol>GroupColumn) then inc(acol);
    if (GroupColumn<>acol) then GroupColumn:=acol;
   end;
end;

Here, grouping is done by setting the GroupColumn property to the column that is clicked. Instead of doing UnGroup when grouping is active and must change to another column, the new group column number is incremented if the grouping is currently active and the current grouped column is located before the clicked column. After this check, the GroupColumn property is set when it differs from the current grouped column.

To add some visual effect for the grouping except the display of the expand / contract nodes, a group header is shown in a different color and to show the effect of the new border capabilities, the OnGetCellBorder is used as well. Setting the color of the group header is done with the OnGetCellColor event handler:

procedure TForm1.AdvStringGrid1GetCellColor(Sender: TObject; ARow,
ACol: Integer; AState: TGridDrawState; ABrush: TBrush; AFont: TFont);
begin
 if AdvStringGrid1.IsNode(arow) then
  begin
   abrush.color:=clGray;
   afont.color:=clWhite;
  end;
end;

The concept is simple : if a row contains a node, ie. it is a group header, then its background color is set to dark gray and the font color to white.

To show vertical borders only, the OnGetCellBorder event is used while the normal gridline display is turned off by setting GridLineWidth to 0.

procedure TForm1.AdvStringGrid1GetCellBorder(Sender: TObject; ARow,
ACol: Integer; APen: TPen; var borders: TCellBorders);
begin
 if not AdvStringgrid1.isNode(arow) and (arow>0) then borders:=[cbLeft];
 apen.color:=clSilver;
end;

A border is drawn at the left side of the cell if it isn't a group header and the border color is set to clSilver.

Delphi project & source files for downloading included in the main demos distribution for Delphi.