Bind to data
Binding TDataGridEh to table/list data
The TDataGridEh is connected to the data list via the DataSource property of the TComponent type.
The TDataGridEh.DataSource property can be assigned components of the following types:
TDataSourcetype. With this connection, the grid will work via the standardTDataGridEh-TDataSetTableLinkEh-TDataSource-TDataSetlink. In this case, the grid creates an internalTDataSetTableLinkEhobject and uses it to create the specified link.TDataSettype. With this connection, the grid will work via the standardTDataGridEh-TDataSetTableLinkEh-TDataSource-TDataSetlink. In this case, the grid will create internalTDataSourceandTDataSetTableLinkEhobjects and use them to create the specified link.TDataSetTableLinkEhtype. With this connection, the grid will work via theTDataGridEh-TDataSetTableLinkEh-TDataSource-TDataSetlink. In this case, the developer must createTDataSourceandTDataSetobjects in advance and connect them to the specifiedTDataSetTableLinkEhobject.TListTableLinkEhtype. This class is designed to connectTDataGridEhto an data object of the TList type.TListTableLinkEh\<T>type. This class is designed to connectTDataGridEhto an data object of the TList<T> type.
In the current version of the library, when connecting a data source of type TListTableLinkEh or TListTableLinkEh\<T> to the grid, the grid can only work in ReadOnly mode.
To connect a grid column to a specific field of a table source, use the TColumnEh.FieldName property.
The simplest example of connecting a TDataGridEh to data
At design-time:
Create an empty
Multi-Device Application – Delphi–>Blank Applicationproject.Drop the
TMemTableEhcomponent onto the Form.Using the component context menu
(Load from file…), load data from the<Path to EhLib Installed folder>\Demos\Vcl\Data\table_country.dfmfile into the componentDrop the
TDataGridEhcomponent onto the FormIn the
Object Inspector, set theDataGridEh1.DataSource = MemTableEh1propertyThe
DataSetdata should appear inDataGridEh1Run the project for testing
In code, connecting DataGrid to TDataSet:
- Create an empty
Multi-Device Application – Delphi–>Blank Applicationproject.
Write next TForm.OnFormCreate event handler:
procedure TForm2.FormCreate(Sender: TObject);
var
MemTableEh1: TMemTableEh;
DataGridEh1: TDataGridEh;
begin
MemTableEh1 := TMemTableEh.Create(Self);
MemTableEh1.LoadFromFile('C:\Users\Public\Documents\Embarcadero\Studio\22.0\'+
'Components\EhLib\Demos\Vcl\Data\table_country.dfm');
MemTableEh1.Active := True;
DataGridEh1 := TDataGridEh.Create(Self);
DataGridEh1.Parent := Self;
DataGridEh1.DataSource := MemTableEh1;
DataGridEh1.SetBounds(10, 10, ClientWidth - 20, ClientHeight - 20);
DataGridEh1.Anchors := [TAnchorKind.akLeft,
TAnchorKind.akTop,
TAnchorKind.akRight,
TAnchorKind.akBottom];
end;In code, connecting DataGrid to TList:
Connecting DataGrid to non-generic TList
To connect the grid to the TList list, you need to create an intermediate object of the TListTableLinkEh type. TListTableLinkEh creates links to the elements of the TList list, and also forms a list of properties of the list element type that will be displayed in the grid as columns.
To connect the TListTableLinkEh object to the TList object, use the TListTableLinkEh.SetList method.
procedure TListTableLinkEh.SetList(AList: TList; AItemTypeInfo: Pointer);The AList parameter is a reference to a list.
The AItemTypeInfo parameter must specify descriptions of the type (pointer to the RTTI) of the list item. To get a reference to the type description, you can use the TypeInfo(const T) function.
Below is an instruction on how to create a simple form with a DataGrid connected to an instance of the TList class:
- Create an empty
Multi-Device Application – Delphi–>Blank Applicationproject.
Drop TDataGridEh and TButton on a Form.
Write next code for TButton.OnClick and TForm.OnDestroy events:
unit Unit1;
interface
uses
System.SysUtils, System.Types, System.UITypes, System.Classes, System.Variants,
FMX.Types, FMX.Controls, FMX.Forms, FMX.Graphics, FMX.Dialogs, EhLibFmx.DataGrid.SearchPanels, EhLibFmx.ToolControls,
EhLibFmx.Grids, EhLibFmx.DataAxisGrids, EhLibFmx.CustomDataGrids, EhLibFmx.DataGrids, FMX.Controls.Presentation,
System.Contnrs,
System.Generics.Collections,
EhLib.TableLinks,
EhLib.TableLink.TypedLists,
FMX.StdCtrls, EhLibFmx.Api;
type
TForm1 = class(TForm)
Button1: TButton;
DataGridEh1: TDataGridEh;
procedure Button1Click(Sender: TObject);
procedure FormDestroy(Sender: TObject);
private
{ Private declarations }
public
FCountryListTableLink: TListTableLinkEh;
FCountryList: TList;
end;
var
Form1: TForm1;
implementation
{$R *.fmx}
type
TCountryInfo = class(TPersistent)
private
FName: String;
FCapital: String;
FContinent: String;
FArea: Integer;
FPopulation: Double;
public
property Name: String read FName write FName;
property Capital: String read FCapital write FCapital;
property Continent: String read FContinent write FContinent;
property Area: Integer read FArea write FArea;
property Population: Double read FPopulation write FPopulation;
end;
procedure TForm1.Button1Click(Sender: TObject);
var
AList: TObjectList;
ListItem: TCountryInfo;
begin
if FCountryListTableLink = nil then
begin
AList := TObjectList.Create;
ListItem := TCountryInfo.Create;
with ListItem do
begin
Name := 'Argentina'; Capital := 'Buenos Aires'; Continent := 'South America'; Area := 2777815; Population := 32300003;
end;
AList.Add(ListItem);
ListItem := TCountryInfo.Create;
with ListItem do
begin
Name := 'Bolivia'; Capital := 'La Paz'; Continent := 'South America'; Area := 1098575; Population := 7300000;
end;
AList.Add(ListItem);
ListItem := TCountryInfo.Create;
with ListItem do
begin
Name := 'Brazil'; Capital := 'Brasilia'; Continent := 'South America'; Area := 8511196; Population := 150400000;
end;
AList.Add(ListItem);
ListItem := TCountryInfo.Create;
with ListItem do
begin
Name := 'Canada'; Capital := 'Ottawa'; Continent := 'North America'; Area := 9976147; Population := 26500000;
end;
AList.Add(ListItem);
FCountryList := AList;
FCountryListTableLink := TListTableLinkEh.Create(nil);
FCountryListTableLink.SetList(FCountryList, TypeInfo(TCountryInfo));
end;
DataGridEh1.DataSource := FCountryListTableLink;
end;
procedure TForm1.FormDestroy(Sender: TObject);
begin
DataGridEh1.DataSource := nil;
FreeAndNil(FCountryListTableLink);
FreeAndNil(FCountryList);
end;
end.Connecting DataGrid to generic TList<T>
- Create an empty
Multi-Device Application – Delphi–>Blank Applicationproject.
Drop TDataGridEh and TButton on a Form.
Write next code for TButton.OnClick event and TForm.OnDestroy:
unit Unit1;
interface
uses
System.SysUtils, System.Types, System.UITypes, System.Classes,
System.Variants,
FMX.Types, FMX.Controls, FMX.Forms, FMX.Graphics, FMX.Dialogs,
EhLibFmx.DataGrid.SearchPanels,
EhLibFmx.ToolControls,
EhLibFmx.Grids,
EhLibFmx.DataAxisGrids,
EhLibFmx.CustomDataGrids,
EhLibFmx.DataGrids,
FMX.Controls.Presentation,
System.Contnrs,
System.Generics.Collections,
EhLib.TableLinks,
EhLib.TableLink.TypedLists,
FMX.StdCtrls;
type
TForm1 = class(TForm)
Button1: TButton;
DataGridEh1: TDataGridEh;
procedure Button1Click(Sender: TObject);
procedure FormDestroy(Sender: TObject);
private
{ Private declarations }
public
FCountryListTableLink: TBaseTableDataLinkEh;
FCountryList: TObject;
end;
var
Form1: TForm1;
implementation
{$R *.fmx}
type
TCountryInfo = class(TPersistent)
private
FName: String;
FCapital: String;
FContinent: String;
FArea: Integer;
FPopulation: Double;
public
property Name: String read FName write FName;
property Capital: String read FCapital write FCapital;
property Continent: String read FContinent write FContinent;
property Area: Integer read FArea write FArea;
property Population: Double read FPopulation write FPopulation;
end;
procedure TForm3.Button1Click(Sender: TObject);
var
AList: TObjectList<TCountryInfo>;
ListItem: TCountryInfo;
begin
if FCountryListTableLink = nil then
begin
AList := TObjectList<TCountryInfo>.Create;
ListItem := TCountryInfo.Create;
with ListItem do
begin
Name := 'Argentina'; Capital := 'Buenos Aires'; Continent := 'South America'; Area := 2777815; Population := 32300003;
end;
AList.Add(ListItem);
ListItem := TCountryInfo.Create;
with ListItem do
begin
Name := 'Bolivia'; Capital := 'La Paz'; Continent := 'South America'; Area := 1098575; Population := 7300000;
end;
AList.Add(ListItem);
ListItem := TCountryInfo.Create;
with ListItem do
begin
Name := 'Brazil'; Capital := 'Brasilia'; Continent := 'South America'; Area := 8511196; Population := 150400000;
end;
AList.Add(ListItem);
ListItem := TCountryInfo.Create;
with ListItem do
begin
Name := 'Canada'; Capital := 'Ottawa'; Continent := 'North America'; Area := 9976147; Population := 26500000;
end;
AList.Add(ListItem);
FCountryList := AList;
FCountryListTableLink := TListTableLinkEh<TCountryInfo>.Create(nil);
TListTableLinkEh<TCountryInfo>(FCountryListTableLink).SetList(AList);
end;
DataGridEh1.DataSource := FCountryListTableLink;
end;
procedure TForm1.FormDestroy(Sender: TObject);
begin
DataGridEh1.DataSource := nil;
FreeAndNil(FCountryListTableLink);
FreeAndNil(FCountryList);
end;
end.Connecting DataGrid to a list with passing a list of properties.
When calling the SetList method, you can pass a list of properties to display in the grid.
The list of properties is passed as an array of strings:
TListTableLinkEh(FCountryListTableLink).SetList(AList,
TypeInfo(TCountryInfo),
['Name', 'Capital']);Or as array of TListTableLinkPropInfoEh. The TListTableLinkPropInfoEh record contains two properties: PropName - the name of the property and DisplayCaption - the title of the property in the grid.
TListTableLinkEh(FCountryListTableLink).SetList(AList, TypeInfo(TCountryInfo),
[ListTableLinkPropInfoEh('Name', 'County Name'),
ListTableLinkPropInfoEh('Capital', 'County Capital')]);If the list items contain nested properties, to display a nested property, specify the full name of the property, separating the nesting level with a period.
TListTableLinkEh(FCallsListTableLink).SetList(ACallList,
TypeInfo(TCallData),
[ListTableLinkPropInfoEh('IncomeCallClient.ID', 'IncomeId'),
ListTableLinkPropInfoEh('IncomeCallClient.Name', 'IncomeName'),
ListTableLinkPropInfoEh('OutcomeCallClient.Id', 'OutcomeId'),
ListTableLinkPropInfoEh('OutcomeCallClient.Name', 'OutcomeName'),
ListTableLinkPropInfoEh('CallDateTime', '')]
);Features of interaction between the DataGrid and the Data list.
When building a link between the grid and the data source, the grid creates an internal buffer object of the TXXXTableDataLinkEh type (TDataSetTableLinkEh, TListTableLinkEh, TListTableLinkEh\<T>) in which the values of the data source records are stored.
When viewing, sorting and filtering data in the grid, the data is sorted and filtered only in the array of the TBaseTableDataLinkEh class. There is no access to the TDataSet.Filter properties or other TDataSet properties. For this reason, the filtering and sorting algorithm does not depend on the TDataSet type.
If external methods change data in TDataSet, the buffer reloads all data from TDataSet.
Differences in the operation of Vcl.TDBGridEh and Fmx.TDataGridEh
If you have previously worked with the Vcl.TDBGridEh control from the EhLib.Vcl package, then note the following differences in the Fmx.TDataGridEh control compared to Vcl.TDBGridEh.
Fmx.TDataGridEh, likeVcl.TDBGridEh, allows you to have static and dynamic columns, butFmx.TDataGridEhallows you to create dynamic columns even when the grid already contains static columns defined by the developer. TheAutoGenerateColumnsproperty is responsible for the need to create dynamic columns. If the grid already contains static columns, then dynamic columns will be created only for those fields for which static columns have not yet been created.In
Vcl.TDBGridEhall columns have one typeTColumnEh.Fmx.TDataGridEhcreates its own data type of column for specific type of data.In
Vcl.TDBGridEh, to sort and filter data, it is necessary to register a special moduleEhLibVclXXX, which contains code for registering a class that can sort and filter data in aDataSet.
InFmx.TDataGridEh, data sorting and filtering works automatically regardless of theDataSettype. The sorting and filtering operation is performed in the internal array of records and does not affect the state of theTDataSet.Fmx.TDataGridEhdoes not need to be connected to a DataSet of type TMemTableEh to activate ViewScroll mode and use all the capabilities of the Fmx grid.Fmx.TDataGridEhuses all its capabilities when connected to any type ofDataSet.
