The Virtual Data Pattern
TeeGrid’sTVirtualData class implements a virtual data pattern that decouples the grid’s rendering engine from the underlying data source. This design provides several key benefits:
Data Source Flexibility
Support any data source by implementing a single interface
Lazy Loading
Retrieve only visible cells on-demand for optimal performance
Large Datasets
Handle millions of rows without loading all data into memory
Framework Agnostic
Same data adapter works across VCL, FMX, and Lazarus
How Virtual Data Works
The virtual data pattern operates on a simple principle: the grid never holds the actual data.Key Characteristics
No Data Duplication
The grid holds no copy of your data - it queries the virtual data adapter each time.
TVirtualData Abstract Class
Defined inTee.GridData.pas, this class establishes the contract for all data adapters:
Required Methods
Every TVirtualData implementation must provide:Returns the total number of rows. Return -1 if unknown (streaming data).
Retrieves the display value for a specific cell. This is the most performance-critical method.
Populates the columns collection based on the data structure.
Associates manually-defined columns with data source fields.
Updates a cell value when the user edits it.
Calculates the optimal width for a column based on its content.
Optional Override Methods
AsFloat
AsFloat
AsString result.AutoHeight
AutoHeight
True if implemented, False to use default height.CanExpand
CanExpand
GetDetail
GetDetail
CanSortBy
CanSortBy
True if the column supports sorting.SortBy
SortBy
IsSorted
IsSorted
ReadOnly
ReadOnly
True if the column is read-only. Default returns False.DataType
DataType
Built-in Implementations
TeeGrid provides three production-ready TVirtualData implementations:TVirtualDBData (Tee.GridData.DB)
Connects to TDataSet and TDataSource components. Key Features:- Automatic field-to-column mapping
- Full edit support with Post/Cancel
- Native data type handling
- Bookmark-based navigation
- Master-detail relationships
- Fetch mode configuration (All, Partial, Automatic)
TVirtualData<T> (Tee.GridData.Rtti)
Generic adapter using RTTI for arrays, lists, and objects. Supported Types:TArray<T>- Static arraysTList<T>- Generic listsTObjectList<T>- Object lists- Single records/objects
- 2D arrays (
TArray<TArray<T>>)
TVirtualStringData (Tee.GridData.Strings)
String grid emulation withCells[Col, Row] indexing.
Usage:
Creating Custom Virtual Data
Implementing a custom adapter requires careful attention to performance and correctness.Basic Implementation Template
Performance Optimization
- AsString Optimization
- Count Caching
- AutoWidth Sampling
AsString is called for every visible cell on every paint. Optimize it ruthlessly:Data Change Notifications
Use events to notify the grid of changes:Advanced Features
Master-Detail Support
Custom Sorting
Column Calculations
Testing Virtual Data
Best Practices
Memory Management
Memory Management
- Store only essential state in TVirtualData
- Let the original data source own the actual data
- Clear caches in
Refreshmethod - Don’t store TColumn references (they can be freed/recreated)
Error Handling
Error Handling
- Protect against invalid row/column indices
- Handle data source disconnection gracefully
- Return empty string from AsString on errors (don’t raise)
- Raise exceptions only in SetValue for validation errors
Thread Safety
Thread Safety
- TVirtualData methods are called from UI thread only
- If data source uses background threads, synchronize access
- Use critical sections for shared state
Type Information
Type Information
- Implement DataType() for proper formatting and editors
- Use TagObject to store field/property references
- Return appropriate THorizontalAlign for column types
Next Steps
Data Binding
Understanding the data binding architecture
Custom Data Source
Complete guide to custom implementations
Database Grids
Working with TVirtualDBData
API Reference
Full TVirtualData API documentation
