YOUSEFUL / DELPHI / COMPONENTS

TAtlasGridData

The abstract base of every data source: rows, typed columns, cells, change notification and batching.

Non-visual component Unit Atlas.VGridData · Inherits TComponent · Product Atlas Virtual Grid

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

MemberKindWhat it does
CreateconstructorCreates the source with no listeners.
DestroydestructorBound grids are told through the VCL free notification and unbind themselves.
BeginUpdatemethodStarts a batch: the changes made until the matching EndUpdate reach the listeners as one notification.
EndUpdatemethodEnds a batch.
AddListenermethodRegisters a method that is called, with the source as Sender, after every change or batch.
RemoveListenermethodUnregisters a method.
ColumnTitlemethodTitle of data column Column.
ColumnKindmethodThe TAtlasCellKind of data column Column: how its text is parsed, formatted, aligned, sorted and totalled.
ColumnReadOnlymethodTrue when the column refuses edits.
GetCellmethodThe cell at Column, Row.
SetCellmethodStores a cell.
SetTextmethodParses Text for the column's kind with Settings (see TAtlasCell.TryParse) and stores it with SetCell.
CheckCellmethodRaises EAtlasGridError Column n does not exist or Row n does not exist unless the cell lies inside the data.
RowCountpropertyNumber of rows, from the protected GetRowCount.
ColumnCountpropertyNumber of columns, from the protected GetColumnCount.
VersionpropertyIncreases 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.

pascal
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.

pascal
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.

pascal
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;

TAtlasMemoryData · TAtlasVirtualData · TAtlasPlotData · TAtlasCell · EAtlasGridError

Also in Atlas Virtual Grid

TAtlasVirtualGrid · TAtlasMemoryData · TAtlasVirtualData · TAtlasPlotData