Skip to main content

Overview

TeeGrid’s column system is built on a hierarchical model where columns can contain sub-columns, enabling sophisticated layouts like grouped headers and multi-level column organization.

TColumn Class

The TColumn class (defined in Tee.Grid.Columns.pas) represents a single column in the grid.

Core Properties

Header
TColumnHeader
Configures the column header display:
  • Text: Header caption
  • ParentFormat: Inherit formatting from parent
  • TextAlignment: Automatic or custom alignment
  • Format: Brush, stroke, font, and margins
Width
TColumnWidth
Column width configuration:
  • Automatic: Auto-size based on content
  • Value: Fixed pixel width
  • Percent: Percentage of available width (e.g., 25 for 25%)
Items
TColumns
Collection of sub-columns for hierarchical layouts. When a column has items, it acts as a container/group for its children.
Expanded
Boolean
default:"True"
Controls visibility of sub-columns. When False, child columns are hidden.
Visible
Boolean
default:"True"
Controls column visibility. Hidden columns don’t render or occupy space.
ReadOnly
Boolean
default:"False"
Prevents editing for this column. Users can select but not modify cell values.
Selectable
Boolean
default:"True"
Controls whether cells in this column can be selected.

Formatting Properties

Format
TFormat
Visual formatting:
  • Brush: Background fill
  • Stroke: Border and lines
  • Font: Text appearance
DataFormat
TDataFormat
Data-specific formatting:
  • Float: Number format string (default: “0.###”)
  • Date: Date format string
  • DateTime: DateTime format string
  • Time: Time format string
TextAlign
TTextAlign
Horizontal and vertical text alignment within cells:
Column.TextAlign.Horizontal := THorizontalAlign.Center;
Column.TextAlign.Vertical := TVerticalAlign.Center;
TextAlignment
TColumnTextAlign
  • Automatic: Right-align numbers, left-align text
  • Custom: Use explicitly set TextAlign values
Margins
TMargins
Cell content padding (Left, Top, Right, Bottom).

Advanced Features

Render
TRender
Custom renderer for cell content. Override default text rendering with:
  • Progress bars
  • Images
  • Buttons
  • Charts
  • Custom graphics
Locked
TColumnLocked
Pin columns:
  • None: Normal scrolling
  • Left: Fixed on left side
  • Right: Fixed on right side
ParentFormat
Boolean
default:"True"
When True, inherits formatting from parent column (if nested) or grid cells.
TagObject
TObject
User-defined object reference. TeeGrid uses this internally to link columns to data fields/properties.
EditorClass
TClass
Custom editor control class for cell editing. Override default TEdit behavior.

TColumns Collection

The TColumns class manages a collection of TColumn objects.

Creating Columns

var
  Col: TColumn;
begin
  // Add empty column
  Col := TeeGrid1.Columns.Add;
  Col.Header.Text := 'Name';
  
  // Add with text
  Col := TeeGrid1.Columns.Add('Email');
end;

Column Spacing

// Set spacing between columns
TeeGrid1.Columns.Spacing.Value := 2; // 2 pixels between columns

Hierarchical Columns

TeeGrid supports nested columns for grouped headers and complex layouts:
var
  Group: TColumn;
begin
  // Create a parent column group
  Group := TeeGrid1.Columns.Add('Personal Info');
  
  // Add child columns
  Group.Items.Add('First Name');
  Group.Items.Add('Last Name');
  Group.Items.Add('Age');
  
  // Create another group
  Group := TeeGrid1.Columns.Add('Contact');
  Group.Items.Add('Email');
  Group.Items.Add('Phone');
  
  // Can nest multiple levels
  with Group.Items.Add('Address') do
  begin
    Items.Add('Street');
    Items.Add('City');
    Items.Add('ZIP');
  end;
end;
Visual Result:
┌────────────────────────────┬─────────────────────────────────────┐
│      Personal Info         │             Contact                 │
├──────────┬──────────┬──────┼──────────┬────────┬────────────────┤
│First Name│Last Name │  Age │  Email   │ Phone  │    Address     │
│          │          │      │          │        ├─────┬────┬─────┤
│          │          │      │          │        │Street│City│ ZIP │
├──────────┴──────────┴──────┴──────────┴────────┴─────┴────┴─────┤
│                         Data Rows...                              │

Working with Hierarchy

// Collapse a column group (hides child columns)
TeeGrid1.Columns[0].Expanded := False;

// Expand it again
TeeGrid1.Columns[0].Expanded := True;

// Check if column has children
if TeeGrid1.Columns[0].HasItems then
  ShowMessage('This column has sub-columns');

Column Width Management

TeeGrid provides flexible width calculation:

Automatic Width

// Auto-size based on content
Column.Width.Automatic := True;

// Grid calculates width by:
// 1. Measuring header text
// 2. Calling TVirtualData.AutoWidth() for content
// 3. Taking the maximum

Fixed Width

// Set explicit pixel width
Column.Width.Automatic := False;
Column.Width.Value := 150;

Percentage Width

// Use percentage of available width
Column.Width.Automatic := False;
Column.Width.Percent := 25; // 25% of grid width

Mixed Widths

// Combine different width types
TeeGrid1.Columns[0].Width.Value := 50;      // Fixed 50px
TeeGrid1.Columns[1].Width.Automatic := True; // Auto-size
TeeGrid1.Columns[2].Width.Percent := 30;    // 30% of remaining space
TeeGrid1.Columns[3].Width.Percent := 70;    // 70% of remaining space

Locked Columns

Freeze columns at the left or right edge:
// Lock first column (e.g., ID or Name)
TeeGrid1.Columns[0].Locked := TColumnLocked.Left;

// Lock last column (e.g., Total or Actions)
TeeGrid1.Columns[TeeGrid1.Columns.Count - 1].Locked := TColumnLocked.Right;

// Locked columns remain visible while others scroll horizontally

Custom Column Events

OnPaint Event

Customize cell painting on a per-column basis:
procedure TForm1.ColumnPaint(const Sender: TColumn; var AData: TRenderData; 
  var DefaultPaint: Boolean);
begin
  // Custom painting for this column
  if AData.Row mod 2 = 0 then
    AData.Painter.Fill(AData.Rect, TColors.LightGray);
  
  // Set DefaultPaint := False to skip default rendering
end;

begin
  TeeGrid1.Columns[2].OnPaint := ColumnPaint;
end;

Visible Columns

Internal helper class TVisibleColumns tracks currently visible columns:
// TeeGrid uses this internally to:
// - Determine which columns to render
// - Handle mouse hit testing
// - Calculate scrollbar ranges
// - Navigate with keyboard (Tab, arrow keys)

Indicator Column

Special column showing row state:
// Configure indicator
TeeGrid1.Indicator.Visible := True;
TeeGrid1.Indicator.Width.Value := 20;
TeeGrid1.Indicator.Format.Brush.Color := TColors.LightBlue;

// The indicator shows:
// - Triangle for current row
// - Different symbols for edit/insert state

Column Reordering

Columns can be moved programmatically:
var
  Col: TColumn;
begin
  // Move column from position 2 to position 0
  Col := TeeGrid1.Columns[2];
  Col.Index := 0;
  
  // Or swap two columns
  TeeGrid1.Columns[0].Index := 3; // Moves column 0 to position 3
end;

Data Type Alignment

Automatic alignment based on data types:
// When TextAlignment = Automatic (default):
// - Numbers: Right-aligned
// - Dates/Times: Center-aligned
// - Strings: Left-aligned
// - Booleans: Center-aligned

// Override for specific column:
Column.TextAlignment := TColumnTextAlign.Custom;
Column.TextAlign.Horizontal := THorizontalAlign.Center;

Column Iteration

var
  Column: TColumn;
  I: Integer;
begin
  // Simple iteration
  for I := 0 to TeeGrid1.Columns.Count - 1 do
  begin
    Column := TeeGrid1.Columns[I];
    // Process column
  end;
  
  // Include nested columns
  procedure ProcessColumns(Columns: TColumns);
  var
    I: Integer;
  begin
    for I := 0 to Columns.Count - 1 do
    begin
      // Process this column
      ShowMessage(Columns[I].Header.Text);
      
      // Recurse into children
      if Columns[I].HasItems then
        ProcessColumns(Columns[I].Items);
    end;
  end;
  
  ProcessColumns(TeeGrid1.Columns);
end;

Column Best Practices

  • Minimize custom painting in OnPaint - it’s called for every visible cell
  • Use ParentFormat := True when possible to reduce memory
  • Avoid complex calculations in data format strings
  • Use descriptive header text
  • Set appropriate column widths for content type
  • Consider locked columns for key fields
  • Make calculated/read-only columns obviously non-editable
  • Limit nesting to 2-3 levels for readability
  • Use meaningful group names
  • Consider whether hierarchy adds value vs complexity
  • Use consistent date/number formats across similar columns
  • Align numbers to the right for easy comparison
  • Apply data formats at column level, not in AsString()

Common Patterns

Calculated Column

var
  TotalCol: TColumn;
begin
  // Add calculated column
  TotalCol := TeeGrid1.Columns.Add('Total');
  TotalCol.ReadOnly := True;
  TotalCol.DataFormat.Float := '$0.00';
  
  // Calculation happens in TVirtualData.AsString()
end;

Image Column

uses Tee.Grid.Columns, Tee.Renders;

var
  ImageCol: TColumn;
begin
  ImageCol := TeeGrid1.Columns.Add('Photo');
  ImageCol.Render := TImageRender.Create(TeeGrid1);
  ImageCol.Width.Value := 100;
end;

Boolean Column (Checkboxes)

var
  BoolCol: TColumn;
begin
  BoolCol := TeeGrid1.Columns.Add('Active');
  // TeeGrid automatically renders booleans as checkboxes
  BoolCol.TextAlign.Horizontal := THorizontalAlign.Center;
end;

Next Steps

Custom Renderers

Create custom column rendering

Data Binding

Learn how columns connect to data

Locked Columns

Deep dive into column freezing

TColumn API

Complete API reference