YOUSEFUL / DELPHI / COMPONENTS
TAtlasGridData
The abstract base of every data source: rows, typed columns, cells, change notification and batching.
Description
A data source is a non-visual component that a TAtlasVirtualGrid reads through GetCell and writes through SetText and SetCell. Rows and columns are numbered from 0. Several grids may watch one source, and either side may be destroyed first.
Writing your own. Override the protected GetRowCount and GetColumnCount, and the public ColumnTitle, ColumnKind and GetCell. To accept edits, also override ColumnReadOnly and SetCell; by default every column is read-only and SetCell raises. After anything changes, call the protected procedure Changed;. It increases Version and calls the listeners, or waits for EndUpdate inside a batch. Raise EAtlasGridError from SetCell to refuse a value; CheckCell raises the standard out-of-range errors. This is the extension point for other storage, such as a TDataSet, for which the product provides no source.
Sources have no locking; create, change and read them on the main thread.
Members
| Member | Kind | What it does |
|---|---|---|
Create | constructor | Creates the source with no listeners. |
Destroy | destructor | Bound grids are told through the VCL free notification and unbind themselves. |
BeginUpdate | method | Starts a batch: the changes made until the matching EndUpdate reach the listeners as one notification. |
EndUpdate | method | Ends a batch. |
AddListener | method | Registers a method that is called, with the source as Sender, after every change or batch. |
RemoveListener | method | Unregisters a method. |
ColumnTitle | method | Title of data column Column. |
ColumnKind | method | The TAtlasCellKind of data column Column: how its text is parsed, formatted, aligned, sorted and totalled. |
ColumnReadOnly | method | True when the column refuses edits. |
GetCell | method | The cell at Column, Row. |
SetCell | method | Stores a cell. |
SetText | method | Parses Text for the column's kind with Settings (see TAtlasCell.TryParse) and stores it with SetCell. |
CheckCell | method | Raises EAtlasGridError Column n does not exist or Row n does not exist unless the cell lies inside the data. |
RowCount | property | Number of rows, from the protected GetRowCount. |
ColumnCount | property | Number of columns, from the protected GetColumnCount. |
Version | property | Increases on every change, including each change inside a batch and once more when the batch ends. |
Constructors
Create constructor
constructor Create(AOwner: TComponent); override;Creates the source with no listeners.
Destructors
Destroy destructor
destructor Destroy; override;Bound grids are told through the VCL free notification and unbind themselves. A grid destroyed later may still call RemoveListener safely.
Properties
RowCount property
property RowCount: Integer read GetRowCount;Number of rows, from the protected GetRowCount.
ColumnCount property
property ColumnCount: Integer read GetColumnCount;Number of columns, from the protected GetColumnCount.
Version property
property Version: Integer read FVersion;Increases on every change, including each change inside a batch and once more when the batch ends.
Methods
BeginUpdate method
procedure BeginUpdate;Starts a batch: the changes made until the matching EndUpdate reach the listeners as one notification. Batches nest.
EndUpdate method
procedure EndUpdate;Ends a batch. When the outermost batch ends and something changed, the listeners are called once. An EndUpdate without a BeginUpdate is ignored.
AddListener method
procedure AddListener(const Listener: TNotifyEvent);Registers a method that is called, with the source as Sender, after every change or batch. Adding the same method twice registers it once.
RemoveListener method
procedure RemoveListener(const Listener: TNotifyEvent);Unregisters a method. Safe during a notification and after the source has begun to be destroyed.
ColumnTitle method
function ColumnTitle(Column: Integer): string; virtual; abstract;Title of data column Column. The grid shows it unless the grid column has its own Title.
ColumnKind method
function ColumnKind(Column: Integer): TAtlasCellKind; virtual; abstract;The TAtlasCellKind of data column Column: how its text is parsed, formatted, aligned, sorted and totalled.
ColumnReadOnly method
function ColumnReadOnly(Column: Integer): Boolean; virtual;True when the column refuses edits. The base class returns True for every column.
GetCell method
function GetCell(Column, Row: Integer): TAtlasCell; virtual; abstract;The cell at Column, Row. Sources raise EAtlasGridError outside the data.
SetCell method
procedure SetCell(Column, Row: Integer; const Cell: TAtlasCell); virtual;Stores a cell. The base class raises EAtlasGridError This data source is read-only.
SetText method
procedure SetText(Column, Row: Integer; const Text: string; const Settings: TFormatSettings);Parses Text for the column's kind with Settings (see TAtlasCell.TryParse) and stores it with SetCell. Raises EAtlasGridError for a cell outside the data and for text that does not parse, for example "abc" is not a number; the stored value is unchanged. Not virtual: override SetCell instead.
Orders.SetText(1, 0, '1300.75', TFormatSettings.Invariant);CheckCell method
procedure CheckCell(Column, Row: Integer);Raises EAtlasGridError Column n does not exist or Row n does not exist unless the cell lies inside the data. Call it first in your own GetCell and SetCell.
Examples
Write a read-only source
A multiplication table computed on demand. Setting Size := 12 shows 12 x 12 cells; the bottom-right one reads 144. Bind it after setting Size, or call the grid's ResetColumns, because a grid bound to a source without columns creates none.
uses System.SysUtils, Atlas.VGridData;
type
// A read-only multiplication table. A source must provide GetRowCount,
// GetColumnCount, ColumnTitle, ColumnKind and GetCell, and call Changed.
TTimesTable = class(TAtlasGridData)
private
FSize: Integer;
procedure SetSize(Value: Integer);
protected
function GetRowCount: Integer; override;
function GetColumnCount: Integer; override;
public
function ColumnTitle(Column: Integer): string; override;
function ColumnKind(Column: Integer): TAtlasCellKind; override;
function GetCell(Column, Row: Integer): TAtlasCell; override;
property Size: Integer read FSize write SetSize;
end;
procedure TTimesTable.SetSize(Value: Integer);
begin
if Value < 0 then raise EAtlasGridError.Create('Size cannot be negative');
FSize := Value;
Changed; // tells every watching grid
end;
function TTimesTable.GetRowCount: Integer;
begin
Result := FSize;
end;
function TTimesTable.GetColumnCount: Integer;
begin
Result := FSize;
end;
function TTimesTable.ColumnTitle(Column: Integer): string;
begin
Result := 'x ' + IntToStr(Column + 1);
end;
function TTimesTable.ColumnKind(Column: Integer): TAtlasCellKind;
begin
Result := ckNumber;
end;
function TTimesTable.GetCell(Column, Row: Integer): TAtlasCell;
begin
CheckCell(Column, Row); // EAtlasGridError outside the table
Result := TAtlasCell.OfNumber((Row + 1) * (Column + 1));
end;
Watch a source from your own code
Register with Orders.AddListener(Counter.DataChanged) and unregister with RemoveListener before freeing the counter. Loading the three orders in one BeginUpdate/EndUpdate batch calls it once, with 3 rows.
uses Atlas.VGridData;
type
TOrderCounter = class
Changes: Integer;
procedure DataChanged(Sender: TObject);
end;
procedure TOrderCounter.DataChanged(Sender: TObject);
begin
Inc(Changes);
Writeln(TAtlasGridData(Sender).RowCount, ' rows, version ', TAtlasGridData(Sender).Version);
end;
Related
TAtlasMemoryData · TAtlasVirtualData · TAtlasPlotData · TAtlasCell · EAtlasGridError
Also in Atlas Virtual Grid
TAtlasVirtualGrid · TAtlasMemoryData · TAtlasVirtualData · TAtlasPlotData