TTMSFNCDataBinding
To get started with the databinding component, drop a TTMSFNCDataBinder
(further referred to as databinder) component on the form. The databinder component is capable of binding single value components, lists, tables and grids as well as non published properties such as generic TList
& TObjectList
(Integer
or String
based). Note that the databinder component is currently only supporting retrieval and display of data. It also automatically updates when a dataset change occurs.
The chapters below demonstrate what is possible based on a TClientDataSet
connected to the biolife.xml
file provided by Embarcadero, a TDataSource
and a single instance of
TTMSFNCDataBinder
.
Binding a single value
Binding a single value can be done by adding an item to the databinder component, specifying the component, the field name and the property name. It shows the value based on the active record. There are several ways that this can be done.
Programmatically
procedure TFormDataBinding.UpdateLinks;
var
it: TTMSFNCDataBinderItem;
begin
TMSFNCDataBinder1.BeginUpdate;
it := TMSFNCDataBinder1.Items.Add;
it.&Object := TMSFNCHTMLText1;
it.BindType := dbbtSingleValue;
it.DataSource := DataSource1;
it.FieldName := 'Common_Name';
it.PropertyName := 'Text';
TMSFNCDataBinder1.EndUpdate;
TMSFNCDataBinder1.Active := True;
end;
ConnectSingle
.
procedure TFormDataBinding.UpdateLinks;
begin
TMSFNCDataBinder1.ConnectSingle(TMSFNCHTMLText1, DataSource1, 'Text', 'Common_Name');
TMSFNCDataBinder1.Active := True;
end;
Designtime
The databinder component also registered designtime support retrieving components, fieldnames and properties and makes this easily selectable at designtime via the object inspector. Add an item to the Items
collection inside the TTMSFNCDataBinder
component, select the item in the object inspector and select the values necessary to bind a single value to the component as demonstrated below.
Result:
Binding a list (TStringList)
Binding a list is similar to binding a single value but it shows all the records in the dataset.
procedure TFormDataBinding.UpdateLinks;
var
it: TTMSFNCDataBinderItem;
begin
TMSFNCDataBinder1.BeginUpdate;
it := TMSFNCDataBinder1.Items.Add;
it.&Object := ListBox1;
it.BindType := dbbtList;
it.DataSource := DataSource1;
it.FieldName := 'Common_Name';
it.PropertyName := 'Items';
TMSFNCDataBinder1.EndUpdate;
TMSFNCDataBinder1.Active := True;
end;
procedure TFormDataBinding.UpdateLinks;
begin
TMSFNCDataBinder1.ConnectList(ListBox1, DataSource1, 'Items', 'Common_Name');
TMSFNCDataBinder1.Active := True;
end;
Binding a list (TCollection)
Binding a list based on TCollection
is similar to binding a list based on TStringList
. When binding a TStringList
based component it is sufficient to set the property that represents the list
(Items
in case of a TListBox
). Some components have a collection to represent the items and when using the above, it will add items to the collection but not visualize the content, as typically there is a Caption
or Text
property inside the TCollectionItem
that is used to display the values inside the list.
To work with a TCollection
instead of a TStringList
in the databinder, you need to use the SubPropertyNames
& the SubFieldNames
collection and this immediately allows you to bind more than one sub-property. The PropertyName
remains “Items”
, but for each collection item that is automatically added to the “Items”
collection, the SubPropertyNames
& SubFieldNames
collection specifies which properties of that item are bound to which fields. For each item inside the SubPropertyNames
there is an equivalent in the SubFieldNames
and vice versa. Below is a sample
based on the TTMSFNCListBox
component.
procedure TFormDataBinding.UpdateLinks;
var
it: TTMSFNCDataBinderItem;
begin
TMSFNCDataBinder1.BeginUpdate;
it := TMSFNCDataBinder1.Items.Add;
it.&Object := TMSFNCListBox1;
it.BindType := dbbtList;
it.DataSource := DataSource1;
it.PropertyName := 'Items';
it.SubPropertyNames.Add.Value := 'Text';
it.SubFieldNames.Add.Value := 'Common_Name';
TMSFNCDataBinder1.EndUpdate;
TMSFNCDataBinder1.Active := True;
end;
procedure TFormDataBinding.UpdateLinks;
begin
TMSFNCDataBinder1.ConnectList(TMSFNCListBox1, DataSource1, 'Items', ['Text'], ['Common_Name']);
TMSFNCDataBinder1.Active := True;
end;
procedure TFormDataBinding.FormCreate(Sender: TObject);
begin
TMSFNCListBox1.DefaultItem.BitmapWidth := 32;
TMSFNCListBox1.DefaultItem.BitmapHeight := 32;
TMSFNCListBox1.ItemsAppearance.HeightMode := lihmVariable;
TMSFNCDataBinder1.ConnectList(TMSFNCListBox1, DataSource1, 'Items', ['Text', 'Bitmap'], ['Common_Name', 'Graphic']);
TMSFNCDataBinder1.Active := True;
end;

Binding a column/list will retrieve all fields and all records and display them in a column/list structure. This means that the component you want to bind needs to have a separate column and a list collection.
procedure TFormDataBinding.FormCreate(Sender: TObject);
begin
TMSFNCDataBinder1.ConnectColumnList(TMSFNCTreeView1, DataSource1, 'Nodes', 'Columns', 'Text', 'Values.Text');
TMSFNCDataBinder1.Active := True;
end;
Binding a grid
Binding a grid is only possible when the component you are targeting implements the
ITMSFNCDataBinderGrid
interface. You can either use the interface, or redefine the interface with the correct GUID.
ITMSFNCDataBinderBase = interface
['{778B63C9-34E3-4B65-A6B8-85E3EB1D17C3}']
procedure DataBeginUpdate;
procedure DataEndUpdate;
end;
ITMSFNCDataBinderGrid = interface(ITMSFNCDataBinderBase)
['{D23BDEAA-49B1-451A-9401-0D0D11A9957A}']
procedure SetDataColumnCount(AValue: Integer);
procedure SetDataRowCount(AValue: Integer);
procedure ClearData;
function GetDataRowCount: Integer;
procedure SetDataValue(AColumn, ARow: Integer; AValue: string);
procedure SetDataHeader(AColumn: Integer; AValue: string);
end;
Then after implementing the correct interfaces, you can use the following code to bind to a grid
procedure TFormDataBinding.FormCreate(Sender: TObject);
begin
TMSFNCDataBinder1.ConnectGrid(TMSFNCGrid1, DataSource1);
TMSFNCDataBinder1.Active := True;
end;
Binding a TList/TObjectList
Next to TStringList
& TCollection
there is also support for TList
& TObjectList
properties based on Integer
& Strings
. The sample below defines a TPersistent
object with 2 published properties, bound to a data source.
TListObject = class(TPersistent)
private
FL: TList<Integer>;
FS: TList<string>;
public
constructor Create;
destructor Destroy; override;
published
property L: TList<Integer> read FL;
property S: TList<string> read FS;
end;
procedure TFormDataBinding.Bind;
var
o: TListObject;
begin
o := TListObject.Create;
try
TMSFNCDataBinder1.Items.Clear;
TMSFNCDataBinder1.ConnectList(o, DataSource1, 'L', [], ['Price']);
TMSFNCDataBinder1.ConnectList(o, DataSource1, 'S', [], ['Brand']);
o.Log;
ClientDataSet1.First;
ClientDataSet1.Edit;
ClientDataSet1.Fields[1].AsString := 'Hello World!';
ClientDataSet1.Post;
o.Log;
finally
o.Free;
end;
end;
Result
Debug Output:
{"$type":"TListObject","L":[699000,1268000,2096000,2000000,3881000,1659000,929000,9740500,690
000,2010000,2035825,1175000,4779500,3950000,1685000,1259000,7410000,4537000,12445000,9065
00,1053000],"S":["Alfa Romeo","MERCEDES","TVR","Wiesmann","Honda","Lexus","Mazda","Rolls
Royce","Audi","JAGUAR","MASERATI","LOTUS","FERRARI","BMW","PORSCHE","PEUGEOT","LAMBORGHINI"
,"DE TOMASO","MERCEDES","MG","Chrysler"]} Process DataBindingTest.exe (1612)
And the result after editing a value to “Hello World!”
Debug Output:
{"$type":"TListObject","L":[699000,1268000,2096000,2000000,3881000,1659000,929000,9740500,690
000,2010000,2035825,1175000,4779500,3950000,1685000,1259000,7410000,4537000,12445000,9065
00,1053000],"S":["Hello World","MERCEDES","TVR","Wiesmann","Honda","Lexus","Mazda","Rolls
Royce","Audi","JAGUAR","MASERATI","LOTUS","FERRARI","BMW","PORSCHE","PEUGEOT","LAMBORGHINI"
,"DE TOMASO","MERCEDES","MG","Chrysler"]} Process DataBindingTest.exe (14732)
Sub collections
In the binding column/list chapter, you can see the sub property that is being targeted for the TTMSFNCTreeView
“Nodes”
collection is “Values.Text”
. There is ofcourse no property named this way, but when activating the database adapter, the “Nodes”
collection is filled with items. Each item represents a node (TTMSFNCTreeViewNode
), and each node has a property called “Values”
. This represents the value for each column. When adding a TTMSFNCTreeViewNodeValue
inside the “Values”
collection, you can set a “Text”
property that will then be displayed in the treeview. To make this work we have added support in the database adapter to go a level deeper when necessary. When the sub property under the main property is also a TCollection
, it will add a value and then access the property afterwards and set the value of the field accordingly.
TMSFNCDataBinder1.ConnectList(TMSFNCTreeView1, DataSource1, 'Nodes', ['Values.Text', 'Values.Text', 'Values.CollapsedIcon'], ['Common_Name', 'Category', 'Graphic']);
HTML Template
For the single value and list bindings, there is support to add a HTML template instead of binding to a specific field name. The HTML template supports multiple fields as long as they follow a specific kind of format. The HTML itself is based on the mini HTML reference https://www.tmssoftware.com/site/minihtml.asp
The format for adding fields is: <#FIELDNAME>
.
So when applying this to the single value binding for example we can add an item using the
TMSFNCDataBinder1.ConnectSingleHTMLTemplate(TMSFNCHTMLText1, DataSource1, 'Text', '<b>Name: <#COMMON_NAME></b><br/><#NOTES>');
procedure TFormDataBinding.UpdateLinks;
var
it: TTMSFNCDataBinderItem;
begin
TMSFNCDataBinder1.BeginUpdate;
it := TMSFNCDataBinder1.Items.Add;
it.&Object := TMSFNCHTMLText1;
it.BindType := dbbtSingleValue;
it.DataSource := DataSource1;
it.PropertyName := 'Text';
it.HTMLTemplate := '<b>Name: <#COMMON_NAME></b><br/><#NOTES>';
TMSFNCDataBinder1.EndUpdate;
TMSFNCDataBinder1.Active := True;
end;
Editor
The databinder component installs an editor that is available at designtime and at runtime. To start it at runtime, call
At designtime, you can right-click the editor and select“Edit…”
to start the editor.
The editor allows you to edit, add and delete bindings. Click on Edit Mode
to make changes to existing bindings. Click on the +
sign at the top left to add a new binding and when in edit mode, select new components to start a new configuring a new binding. The comboboxes will list properties based on the bind component and the datasource. The datasource can be selected in the upper right corner next to the bind type.