Table of Contents

Column management

Hide, reorder, freeze, fix and resize columns — programmatically or via the built-in columns editor dialog.

Overview

Three orthogonal column behaviours, each with its own count property:

Property Effect
FixedColumnCount Columns at the left edge that never scroll. Headers and row-number columns.
FixedRightColumnCount Same, but at the right edge.
FreezeColumnCount Like fixed, but the user can scroll past them. Common for keeping ID/name columns visible while exploring distant columns.

On top of that, every column can be hidden, resized, and reordered by drag-and-drop.

DataGrid with custom per-column widths and headers DataGrid with custom per-column widths and headers

Quick example

procedure TForm1.FormCreate(Sender: TObject);
begin
  // Fixed (always visible) columns at the leftmost edge
  Grid.FixedColumnCount      := 1;
  Grid.FixedRightColumnCount := 0;

  // Freeze: like fixed, but the user can scroll past these on the right.
  Grid.FreezeColumnCount := 2;

  // Hide column 4 entirely
  Grid.HideColumn(4);

  // Resize specific columns
  Grid.ColumnWidths[0] := 30;
  Grid.AutoSizeColumns;

  // Let the user reorder columns by drag-and-drop on header cells
  Grid.Options.Column.Dragging.Enabled := True;
end;

procedure TForm1.ShowColumnsEditorClick(Sender: TObject);
begin
  // Modal dialog with a checked list of all columns; the user can
  // toggle visibility and reorder with drag-and-drop.
  Grid.ShowColumnsEditor;
end;

Step by step

Access columns

procedure TForm1.AccessColumns;
var
  Col: TTMSFNCDataGridColumn;
begin
  Grid.Columns[2].Header := 'Country';      // by index
  Col := Grid.Columns.ColumnByName('Name'); // by name (returns TTMSFNCDataGridColumn)
end;

Add, insert, and delete columns

Grid.Columns.Add;                         // append via collection
Grid.AddColumn;                           // equivalent convenience method
Grid.Columns.Insert(2);                   // insert before column index 2
Grid.InsertColumn(2);                     // equivalent convenience method
Grid.InsertColumns(2, 3);                 // insert 3 columns starting at index 2
Grid.DeleteColumn(4);                     // remove column 4 and shift left
Grid.DeleteColumns(4, 2);                 // remove 2 columns starting at index 4
Grid.SwapColumns(1, 3);                   // exchange columns 1 and 3 in place
Grid.ColumnCount := 6;                    // set the total column count directly

Add, insert, and delete rows

Grid.AddRow;                              // append a new empty row at the bottom
Grid.InsertRow(2);                        // insert a row before index 2
Grid.InsertRows(2, 5);                    // insert 5 rows starting at index 2
Grid.DeleteRow(4);                        // remove row 4 and shift rows up
Grid.DeleteRows(4, 3);                    // remove 3 rows starting at index 4
Grid.SwapRows(1, 3);                      // exchange rows 1 and 3 in place
Grid.RowCount := 100;                     // set the total row count directly

InsertRow / InsertRows fire OnBeforeInsertRow / OnAfterInsertRow so you can initialise new cells or cancel the insertion. Similarly, InsertColumn fires OnBeforeInsertColumn / OnAfterInsertColumn.

Hide / show

Grid.HideColumn(4);
Grid.UnhideColumn(4);
Grid.UnhideAllColumns;

Equivalent: set Grid.Columns[4].Visible := False.

Resize

Grid.ColumnWidths[0] := 30;
Grid.AutoSizeColumn(2);
Grid.AutoSizeColumns;                      // auto-size every column

AutoSizeColumn measures the widest cell content and sets the width to fit plus a configurable padding (Options.Column.AutoSizePadding).

Reorder

// Allow the user to drag headers
Grid.Options.Mouse.ColumnDragging := True;

// Or move programmatically — column 4 ends up at position 1
Grid.MoveColumn(4, 1);

Options.Mouse.ColumnDragModes is a set — combine modes as needed:

Grid.Options.Mouse.ColumnDragModes := [gcdmReorder];                       // reorder only
Grid.Options.Mouse.ColumnDragModes := [gcdmReorder, gcdmVisualGrouping];   // both

Freeze and fix

Grid.FixedColumnCount      := 1;          // always visible on the left
Grid.FixedRightColumnCount := 1;          // always visible on the right
Grid.FreezeColumnCount     := 2;          // scrollable but "sticky"

Stretch columns to fill available space

Grid.Options.Column.Stretching.Enabled := True;

The default stretch mode (gstmAll) distributes remaining horizontal space across all flexible columns equally. Two additional modes are available:

Stretching.Mode Effect
gstmAll Extra space divided equally across all non-fixed columns (default).
gstmIndex Only the column at Stretching.Index stretches to fill the space.
gstmProportional Distributes extra space proportionally to each column's current width — wider columns gain more pixels.
Grid.Options.Column.Stretching.Mode := gstmProportional;

To stretch a specific column only, set Stretching.Mode := gstmIndex and Stretching.Index to the column index:

Grid.Options.Column.Stretching.Mode  := gstmIndex;
Grid.Options.Column.Stretching.Index := 3;   // column 3 absorbs all extra space

Two-way column and row sizing

By default, dragging the right edge of a column header resizes that column. Enable two-way sizing to allow resizing from either edge:

Grid.Options.Mouse.ColumnSizingMode := gszmTwoSided;  // resize from left or right edge
Grid.Options.Mouse.RowSizingMode    := gszmTwoSided;  // resize from top or bottom edge

The default (gszmOneSided) restricts resizing to the trailing edge only.

ColumnViewMode and RowViewMode

These properties control how RowCount and ColumnCount relate to the visible viewport.

Property value Effect
gcvmTotalColumns (default) ColumnCount is the total number of allocated columns.
gcvmControl ColumnCount is clamped to however many columns fit in the current viewport.
grvmTotalRows (default) RowCount is the total number of allocated rows.
grvmControl RowCount is clamped to however many rows fit in the current viewport.

The default (TotalColumns / TotalRows) is the most common setup and matches the behaviour most code assumes.

Column settings and AddSetting

Every column has a Settings set of type TTMSFNCDataGridColumnSettings. Only properties that are included in this set are applied at render time; everything else falls back to the grid-wide default. The purpose of this design is to let you set a grid-level default once and have columns opt in to owning their own copy of a property without affecting other columns.

procedure TTMSFNCDataGridColumn.AddSetting(ASetting: TTMSFNCDataGridColumnSetting);
begin
  Settings := Settings + [ASetting];   // opt the column in to owning the guarded property
end;

AddSetting is simply Settings := Settings + [ASetting]. Call it whenever you set a column property that the grid honours only when the corresponding setting flag is present:

Setting flag Property it guards
gcsAppearance Appearance (cell fill, font, stroke)
gcsType Type (cell control type — checkbox, button, bitmap, …)
gcsEditor Editor (inplace editor type)
gcsEditorTarget EditorTarget (what the editor modifies)
gcsEditorItems EditorItems (combobox item list)
gcsReadOnly ReadOnly
gcsFormatting Formatting (display format type and string)
gcsFilterButton FilterButton
gcsFilterEditor FilterEditor
gcsFilterEditorType FilterEditorType
gcsFilterDefaultType FilterDefaultType
gcsControlText / gcsControlWidth / gcsControlHeight / gcsControlAlign / gcsControlPosition / gcsControlMargins Embedded control properties

Example:

// Without AddSetting the Editor property has no effect at runtime
Grid.Columns[2].Editor := getComboBox;
Grid.Columns[2].AddSetting(gcsEditor);           // opt this column in

Grid.Columns[2].EditorItems.AddStrings(['Yes', 'No', 'N/A']);
Grid.Columns[2].AddSetting(gcsEditorItems);      // opt this column in to owning its items

Grid.Columns[3].Formatting.&Type := gdftDateTime;
Grid.Columns[3].AddSetting(gcsFormatting);       // opt this column in to owning its format

At design time the Object Inspector adds the necessary settings automatically whenever you change a column property through the IDE. AddSetting is only needed when you configure columns in code.

Open the columns editor

A built-in dialog gives the user a checked list of all columns with drag-and-drop reordering. Show it with:

Grid.ShowColumnsEditor;
DataGrid with column drag and column-management actions enabled DataGrid with column drag and column-management actions enabled (dark theme)

The grid remains the configured owner of the column list; the screenshot shows the grid-side setup and action entry point before the dialog is opened. To customise the dialog (translation, drag-and-drop on/off, visible-only filter), drop a TTMSFNCDataGridColumnsEditor component on the form, point its Renderer at the grid, and call Execute.

Combining column hiding, resizing, and stretching

This example hides a technical ID column, auto-sizes two content columns, enables proportional stretching so the remaining columns fill the available width, and makes the Name column fixed so it stays visible while the user scrolls right:

procedure TForm1.FormCreate(Sender: TObject);
begin
  // Hide the internal ID column — users don't need to see it
  Grid.HideColumn(IdColumn);

  // Auto-size two content columns based on their content
  Grid.AutoSizeColumn(NameColumn);
  Grid.AutoSizeColumn(DescColumn);

  // Stretch all visible columns proportionally to fill the grid width
  Grid.Options.Column.Stretching.Enabled := True;
  Grid.Options.Column.Stretching.Mode    := gstmProportional;

  // Fix the Name column so it never scrolls out of view
  Grid.FixedColumnCount := 1;  // column 0 (Name) stays fixed
end;
  • TTMSFNCDataGridColumn — every column property.
  • Grid.Columns.Add, Insert(Index), ColumnByName(AName)
  • Grid.Columns.ColumnByHeader(AHeader) — returns the TTMSFNCDataGridColumn whose Header text matches AHeader; returns nil when not found.
  • Grid.ColumnByHeader(AHeader) — convenience wrapper on the grid object (same result).
  • Grid.ColumnIndexByHeader(AHeader) — returns the zero-based column index for the given header text; returns -1 when not found.
  • TTMSFNCDataGridColumnSetting — enum of per-column setting flags.
  • TTMSFNCDataGridColumn.AddSetting(ASetting) — opt the column in to owning a property.
  • Grid.AddColumn, InsertColumn(i), InsertColumns(i, Count), DeleteColumn(i), DeleteColumns(i, Count)
  • Grid.AddRow, InsertRow(i), InsertRows(i, Count), DeleteRow(i), DeleteRows(i, Count)
  • Grid.SwapColumns(From, To) — exchange two columns; Grid.SwapRows(From, To) — exchange two rows
  • Grid.MoveColumn(From, To) — insert column at new position, shifting others
  • Grid.FixedColumnCount, FixedRightColumnCount, FreezeColumnCount
  • Grid.HideColumn(i), UnhideColumn(i), UnhideAllColumns
  • Grid.ColumnWidths[i], AutoSizeColumn(i), AutoSizeColumns
  • Grid.Options.Column.StretchingEnabled, Mode (gstmAll / gstmIndex / gstmProportional), Index
  • Grid.Options.Column.AutoSizePadding
  • Grid.Options.Mouse.ColumnDragging, ColumnDragModes, ColumnSizing
  • Grid.Options.Mouse.ColumnSizingMode (gszmOneSided / gszmTwoSided)
  • Grid.Options.Mouse.RowSizingMode (gszmOneSided / gszmTwoSided)
  • Grid.ColumnViewModegcvmTotalColumns / gcvmControl
  • Grid.RowViewModegrvmTotalRows / grvmControl
  • Grid.ShowColumnsEditor
  • TTMSFNCDataGridColumnsEditor
  • OnColumnDropped, OnColumnSized, OnCanDragColumn, OnCanSizeColumn
  • OnAppendColumn, OnCanAppendColumn

See also