Documentation Index Fetch the complete documentation index at: https://mintlify.com/Steema/TeeGrid-VCL-FMX-Samples/llms.txt
Use this file to discover all available pages before exploring further.
TeeGrid’s rendering system allows you to customize how cell content is displayed. You can use built-in renderers like checkboxes and progress bars, or create your own custom renderers for specialized visualization.
Understanding Renders
A renderer is a class derived from TRender that controls how cell content is painted. The base rendering hierarchy:
TRender — Base class with Paint method
TFormatRender — Adds format and borders
TTextRender — Adds text rendering with margins and alignment
TVisibleTextRender — Adds visibility control
Built-in Renderers
Boolean Renderer (Checkboxes)
Display boolean values as checkboxes:
var
BoolRender: TBooleanRender;
begin
BoolRender := TBooleanRender.Create( nil );
// Use checkbox style (default)
BoolRender.Style := TBooleanRenderStyle.Check;
// Configure checkbox appearance
BoolRender.Box.Size := 16 ;
BoolRender.Box.Format.Brush.Color := TColors.White;
BoolRender.Box.Format.Stroke.Color := TColors.DkGray;
// Configure check mark color
BoolRender.CheckFormat.Stroke.Color := TColors.Green;
BoolRender.CheckFormat.Stroke.Size := 2 ;
// Assign to column
TeeGrid1.Columns[ 'Active' ].Render := BoolRender;
end ;
Boolean render styles:
TBooleanRenderStyle.Check — Shows checkbox with checkmark
TBooleanRenderStyle.Text — Shows “True” or “False” as text
Progress Bar Renderer
Display numeric values as progress bars:
var
ProgressRender: TProgressRender;
begin
ProgressRender := TProgressRender.Create( nil );
// Set value range
ProgressRender.Minimum := 0 ;
ProgressRender.Maximum := 100 ;
// Set orientation
ProgressRender.Orientation := TOrientation.Horizontal;
// Style the progress bar
ProgressRender.Format.Brush.Color := TColors.SkyBlue;
ProgressRender.Format.Stroke.Color := TColors.Navy;
ProgressRender.Format.Stroke.Visible := True ;
// Assign to column
TeeGrid1.Columns[ 'Progress' ].Render := ProgressRender;
end ;
Expander Renderer
Create expandable/collapsible cells for hierarchical data:
var
ExpanderRender: TExpanderRender;
begin
ExpanderRender := TExpanderRender.Create( nil );
// Set expander style
ExpanderRender.Style := TExpanderStyle.PlusMinus; // PlusMinus, Triangle, or Arrow
// Configure expand box
ExpanderRender.Box.Size := 12 ;
ExpanderRender.Box.Format.Brush.Color := TColors.White;
ExpanderRender.Box.Format.Stroke.Color := TColors.Black;
// Configure expand symbol
ExpanderRender.ExpandFormat.Stroke.Color := TColors.Blue;
ExpanderRender.ExpandFormat.Stroke.Size := 2 ;
// Handle expansion events
ExpanderRender.OnCanExpand := function( const Sender: TRender;
const ARow: Integer ): Boolean
begin
// Return True if row can expand
Result := HasChildren(ARow);
end ;
ExpanderRender.OnExpand := function( const Sender: TRender;
const ARow: Integer ): Boolean
begin
// Handle row expansion
ToggleRowExpansion(ARow);
Result := IsRowExpanded(ARow);
end ;
TeeGrid1.Columns[ 0 ].Render := ExpanderRender;
end ;
Expander styles:
type
TExpanderStyle = (PlusMinus, Triangle, Arrow);
Password Renderer
Mask text content for password fields:
var
PasswordRender: TPasswordRender;
begin
PasswordRender := TPasswordRender.Create( nil );
// Configure appearance
PasswordRender.Format.Font. Name := 'Courier New' ;
PasswordRender.Format.Font.Size := 10 ;
TeeGrid1.Columns[ 'Password' ].Render := PasswordRender;
// Displays: ********
end ;
Creating Custom Renderers
Basic Custom Renderer
Create a simple custom renderer by overriding the Paint method:
type
TStarRatingRender = class (TTextRender)
public
procedure Paint ( var AData: TRenderData); override ;
end ;
procedure TStarRatingRender.Paint ( var AData: TRenderData);
var
Rating: Integer ;
Stars: string ;
I: Integer ;
begin
// Get rating value (0-5)
Rating := StrToIntDef(AData.Data, 0 );
// Build star string
Stars := '' ;
for I := 1 to 5 do
begin
if I <= Rating then
Stars := Stars + '★' // Filled star
else
Stars := Stars + '☆' ; // Empty star
end ;
// Replace data with stars
AData.Data := Stars;
// Call inherited to paint the text
inherited Paint(AData);
end ;
// Usage
var
StarRender: TStarRatingRender;
begin
StarRender := TStarRatingRender.Create( nil );
StarRender.Format.Font.Size := 16 ;
StarRender.Format.Font.Color := TColors.Gold;
TeeGrid1.Columns[ 'Rating' ].Render := StarRender;
end ;
Advanced Custom Renderer with Graphics
Draw custom graphics in cells:
type
TColorSwatchRender = class (TFormatRender)
private
FSwatchSize: Single ;
public
constructor Create ( const AChanged: TNotifyEvent); override ;
procedure Paint ( var AData: TRenderData); override ;
property SwatchSize : Single read FSwatchSize write FSwatchSize;
end ;
constructor TColorSwatchRender.Create ( const AChanged: TNotifyEvent);
begin
inherited ;
FSwatchSize := 20 ;
end ;
procedure TColorSwatchRender.Paint ( var AData: TRenderData);
var
SwatchRect: TRectF;
Color: TColor;
begin
// Paint background
inherited Paint(AData);
// Parse color from hex string (e.g., "#FF0000")
Color := StringToColor(AData.Data);
// Calculate swatch rectangle
SwatchRect := AData.Bounds;
SwatchRect.Left := SwatchRect.Left + 4 ;
SwatchRect.Top := SwatchRect.Top + (SwatchRect.Height - FSwatchSize) / 2 ;
SwatchRect.Width := FSwatchSize;
SwatchRect.Height := FSwatchSize;
// Draw color swatch
AData.Painter.SetBrush(Format.Brush);
Format.Brush.Color := Color;
AData.Painter.FillRectangle(SwatchRect);
// Draw border around swatch
AData.Painter.SetStroke(Format.Stroke);
Format.Stroke.Color := TColors.Black;
Format.Stroke.Visible := True ;
AData.Painter.DrawRectangle(SwatchRect);
end ;
// Usage
var
ColorRender: TColorSwatchRender;
begin
ColorRender := TColorSwatchRender.Create( nil );
ColorRender.SwatchSize := 24 ;
TeeGrid1.Columns[ 'Color' ].Render := ColorRender;
end ;
Image Renderer
Display images in cells:
type
TImageRender = class (TFormatRender)
private
FStretch: Boolean ;
public
constructor Create ( const AChanged: TNotifyEvent); override ;
procedure Paint ( var AData: TRenderData); override ;
property Stretch : Boolean read FStretch write FStretch;
end ;
constructor TImageRender.Create ( const AChanged: TNotifyEvent);
begin
inherited ;
FStretch := True ;
end ;
procedure TImageRender.Paint ( var AData: TRenderData);
var
ImagePath: string ;
Picture: TPicture;
ImageRect: TRectF;
begin
inherited Paint(AData);
ImagePath := AData.Data;
if FileExists(ImagePath) then
begin
Picture := TPicture.Create( nil );
try
// Load image (implementation depends on VCL/FMX)
Picture.SetGraphic(LoadImageFromFile(ImagePath));
// Calculate image rectangle
ImageRect := AData.Bounds;
ImageRect.Inflate(- 2 , - 2 ); // Add small margin
// Draw image
Picture.Stretch := FStretch;
AData.Painter.Draw(ImageRect, Picture.Internal);
finally
Picture.Free;
end ;
end ;
end ;
Render Data Structure
The TRenderData record passed to Paint contains:
type
TRenderData = record
Bounds: TRectF; // Cell rectangle
Data: String ; // Cell value as string
Painter: TPainter; // Drawing interface
Row: Integer ; // Current row index
function AsBoolean : Boolean ; // Parse data as boolean
procedure ClearData ; // Clear cell data
function IsEmpty : Boolean ; // Check if data is empty
end ;
Text Rendering Options
Text Alignment
Control how text is aligned within cells:
var
TextRender: TTextRender;
begin
TextRender := TTextRender.Create( nil );
// Horizontal alignment
TextRender.TextAlign.Horizontal := THorizontalAlign.Center;
// Options: Left, Center, Right
// Vertical alignment
TextRender.TextAlign.Vertical := TVerticalAlign.Center;
// Options: Top, Center, Bottom
TeeGrid1.Columns[ 'Title' ].Render := TextRender;
end ;
Text Trimming
Handle text overflow:
var
TextRender: TTextRender;
begin
TextRender := TTextRender.Create( nil );
// Enable ellipsis for long text
TextRender.Trimming.Ellipsi := True ;
TextRender.Trimming.Mode := TTrimmingMode.Character;
// Modes: None, Character, Word
TeeGrid1.Columns[ 'Description' ].Render := TextRender;
end ;
Borders and Decorations
Custom Borders
Add borders to individual sides of cells:
var
TextRender: TTextRender;
begin
TextRender := TTextRender.Create( nil );
// Configure individual borders
with TextRender.Borders do
begin
Left.Visible := True ;
Left.Color := TColors.DkGray;
Left.Size := 1 ;
Right.Visible := False ;
Top.Visible := True ;
Top.Color := TColors.LightGray;
Top.Style := TStrokeStyle.Dash;
Bottom.Visible := True ;
Bottom.Color := TColors.Black;
Bottom.Size := 2 ;
end ;
TeeGrid1.Columns[ 0 ].Render := TextRender;
end ;
Hit Testing
Implement custom hit testing for interactive renderers:
type
TButtonRender = class (TTextRender)
public
function Hit ( const R: TRectF; const X, Y: Single ): Boolean ; override ;
procedure Paint ( var AData: TRenderData); override ;
end ;
function TButtonRender.Hit ( const R: TRectF; const X, Y: Single ): Boolean ;
var
ButtonRect: TRectF;
begin
// Calculate button rectangle
ButtonRect := R;
ButtonRect.Inflate(- 4 , - 4 );
// Check if click is within button
Result := ButtonRect. Contains (PointF(X, Y));
end ;
procedure TButtonRender.Paint ( var AData: TRenderData);
var
ButtonRect: TRectF;
begin
ButtonRect := AData.Bounds;
ButtonRect.Inflate(- 4 , - 4 );
// Draw button background
Format.Brush.Color := TColors.SkyBlue;
AData.Painter.FillRectangle(ButtonRect);
// Draw button border
Format.Stroke.Color := TColors.Navy;
Format.Stroke.Size := 1 ;
AData.Painter.DrawRectangle(ButtonRect);
// Draw button text
AData.Painter.SetFont(Format.Font);
AData.Painter.TextOut(ButtonRect, AData.Data, TextAlign);
end ;
Complete Example: Multi-State Icon Renderer
type
TStatusIconRender = class (TTextRender)
public
procedure Paint ( var AData: TRenderData); override ;
end ;
procedure TStatusIconRender.Paint ( var AData: TRenderData);
var
Status: string ;
IconRect: TRectF;
IconColor: TColor;
Icon: string ;
begin
Status := LowerCase(Trim(AData.Data));
// Determine icon and color based on status
case Status of
'active' , 'ok' : begin Icon := '●' ; IconColor := TColors.Green; end ;
'warning' : begin Icon := '▲' ; IconColor := TColors.Orange; end ;
'error' , 'failed' : begin Icon := '■' ; IconColor := TColors.Red; end ;
'pending' : begin Icon := '○' ; IconColor := TColors.Blue; end ;
else
Icon := '?' ; IconColor := TColors.Gray;
end ;
// Draw icon
IconRect := AData.Bounds;
IconRect.Left := IconRect.Left + 8 ;
IconRect.Width := 16 ;
Format.Font.Size := 14 ;
Format.Font.Color := IconColor;
Format.Font.Style := [fsBold];
AData.Painter.SetFont(Format.Font);
var Align := TTextAlign.Create( nil );
try
Align.Horizontal := THorizontalAlign.Left;
Align.Vertical := TVerticalAlign.Center;
AData.Painter.TextOut(IconRect, Icon, Align);
finally
Align.Free;
end ;
// Draw status text
var TextRect := AData.Bounds;
TextRect.Left := IconRect.Right + 4 ;
Format.Font.Size := 10 ;
Format.Font.Color := TColors.Black;
Format.Font.Style := [];
AData.Data := Status;
inherited Paint(AData);
end ;
// Usage
procedure TForm1.SetupStatusColumn ;
var
StatusRender: TStatusIconRender;
begin
StatusRender := TStatusIconRender.Create( nil );
TeeGrid1.Columns[ 'Status' ].Render := StatusRender;
end ;
Best Practices
Keep Paint methods efficient
The Paint method is called for every visible cell. Avoid heavy calculations, file I/O, or object creation inside Paint. Cache resources when possible.
Use inherited Paint wisely
Call inherited Paint(AData) when you want default rendering before or after your custom painting. Don’t call it if you’re completely replacing the default rendering.
Always draw within AData.Bounds. Drawing outside these bounds can cause visual artifacts and overlap with adjacent cells.
Handle empty data gracefully
Check if data is empty or invalid before rendering. Use AData.IsEmpty or validate the data format.
Styling Configure colors, fonts, and borders
TRender API Complete API reference for render classes
TPainter API Drawing interface for custom rendering
Custom Editors Create custom cell editors