Skip to content

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;
The below code actually sets up the same binding as the code above with a convenience method 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.

TMSFNCDataBinding

Result:

TMSFNCDataBinding1

TMSFNCDataBinding2

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;
Again as with the single value binding, the below code uses a convenience method to add an item and set all the properties in one go.
procedure TFormDataBinding.UpdateLinks;
begin
  TMSFNCDataBinder1.ConnectList(ListBox1, DataSource1, 'Items', 'Common_Name');
  TMSFNCDataBinder1.Active := True;
end;
Result:

TMSFNCDataBinding3

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;
or
procedure TFormDataBinding.UpdateLinks;
begin
  TMSFNCDataBinder1.ConnectList(TMSFNCListBox1, DataSource1, 'Items', ['Text'], ['Common_Name']);
  TMSFNCDataBinder1.Active := True;
end;
Below is a sample that demonstrates how to bind more then one property.
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;
TMSFNCDataBinding4

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;

TMSFNCDataBinding5

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;

TMSFNCDataBinding6

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']);

TMSFNCDataBinding7

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>');
or
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;
This will result in:

TMSFNCDataBinding8

Editor

The databinder component installs an editor that is available at designtime and at runtime. To start it at runtime, call

TMSFNCDataBinder1.ShowEditor;
At designtime, you can right-click the editor and select “Edit…” to start the editor.

TMSFNCDataBinding9

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.