One type of link supported by Visual LiveBindings is between simple controls and data source fields. Simple controls are visual components which accept user input to edit a value. TEdit and TCheckBox are examples of simple controls.
After a TEdit and TCheckBox are dropped on a VCL, the controls are represented in the LiveBindings designer (View\LiveBindings designer). The TEdit is shown with the member "Text" and TCheckBox with the member "Checked". These are the control members changed by user input.

The LiveBindings designer can be used to connect these members to data source fields.
The TPrototypeBindSource component is an easy way to create a data source. Drop a TPrototypeBindSource on the form. Right click on it and choose "Add Field…"
Choose a boolean, integer and string field as shown below. You can multiselect the fields or add them one at a time.

The LiveBindings designer shows PrototypeBindSource1 and the new fields:

You can connect the members of the controls to the fields. Note that when a member is selected, other members change color. Green indicates which members can connect.

You can connect them like this (use the rearrange button to get this spacing):

Or try different connections. If LiveBindings can’t convert between the control member type and field type, an error message box is displayed. To switch the links, grab the arrow and move it to another member. If you want to get rid of a link, right click on a line and choose "Remove Link". Multiple controls can link to the same field. But a particular control can only link to one field. If you try to add an additional link to a control, a message box will prompt you about deleting the existing link.
You can add a navigator control by right clicking on the TPrototypeBindSource (in the form designer not the LiveBindings designer) and choosing Add Navigator. Now the app is ready to run.
If you drop a TTrackBar on the form, the LiveBindings designer will display the Trackbar like this:

Notice that the LiveBindings designer doesn’t show a member for TrackBar1. This is because TTrackBar is has not been enabled for LiveBindings.
There are two requirements to LiveBindings-enable a simple control like TTrackBar. The first requirement is that the control implement observer support. LiveBindings depends on observers to subscribe to control notifications. The second requirement is to register the control value name (e.g.; "Position" for TTrackBar). The control value name is used by LiveBindings components to generate expressions which get and set the control’s value.
We can’t directly modify TTrackbar, so observer support must be implemented in a descendent class. I’ve named this class TObservableTrackbar and the unit VCL.Sample.ObservableTrackbar. Here is the interface section:
unit VCL.Sample.ObservableTrackbar;
interface
uses Vcl.ComCtrls, System.Classes, WinApi.Messages, WinApi.CommCtrl, Vcl.Controls;
type
[ObservableMember('Position')]
TObservableTrackBar = class(TTrackBar)
private
procedure CNHScroll(var Message: TWMHScroll); message CN_HSCROLL;
procedure CNVScroll(var Message: TWMVScroll); message CN_VSCROLL;
procedure ObserverToggle(const AObserver: IObserver; const Value: Boolean);
protected
function CanObserve(const ID: Integer): Boolean; override;
procedure ObserverAdded(const ID: Integer; const Observer: IObserver); override;
end;
implementation
uses System.SysUtils;
I’ve included both uses lists in this code snippet to show that there are no references to LiveBindings units. The declarations of observer interfaces, etc. are in System.Classes.
The ObservableMember attribute identifies the control value name for TObservableTrackbar:
[ObservableMember('Position')]
TObservableTrackBar = class(TTrackBar)
Controls which implement observers always override TComponent.CanObserve(). This method identifies the type of observers supported by TObservableTrackbar.
function TObservableTrackBar.CanObserve(const ID: Integer): Boolean;
begin
case ID of
TObserverMapping.EditLinkID,
TObserverMapping.ControlValueID:
Result := True;
else
Result := False;
end;
end;
EditLinkID is the observer that is used for control-to-field links.
The overrides for CNHscroll and CNVScroll are where TObserverableTrackBar calls the observable interfaces to notify LiveBindings components when the user moves the thumb.
procedure TObservableTrackBar.CNHScroll(var Message: TWMHScroll);
var
LPosition: Integer;
begin
LPosition := Position;
inherited;
if LPosition <> Position then
TLinkObservers.ControlChanged(Self);
end;
procedure TObservableTrackBar.CNVScroll(var Message: TWMVScroll);
var
LPosition: Integer;
begin
Message.Result := 0;
LPosition := Position;
inherited;
if LPosition <> Position then
TLinkObservers.ControlChanged(Self);
end;
These two overrides are sufficient to monitor user input to TObservableTrackbar. TLinkObservers.ControlChanged is a utility method that does most of the work. You can find the implementation in System.Classes.
The following methods prevent the user from moving the thumb when TObservableTrackBar is linked to a read-only field.
procedure TObservableTrackBar.ObserverAdded(const ID: Integer;
const Observer: IObserver);
begin
if ID = TObserverMapping.EditLinkID then
Observer.OnObserverToggle := ObserverToggle;
end;
procedure TObservableTrackBar.ObserverToggle(const AObserver: IObserver;
const Value: Boolean);
var
LEditLinkObserver: IEditLinkObserver;
begin
if Value then
begin
if Supports(AObserver, IEditLinkObserver, LEditLinkObserver) then
// Disable the trackbar if the associated field does not support editing
Enabled := not LEditLinkObserver.IsReadOnly;
end
else
Enabled := True;
end;
All controls which support the EditLink observer, should prevent the user from changing the control value. Disabling the control is one way to do it. Some observer implementations ignore certain types of input to prevent the user from changing the control value.
On more piece of code is needed to make TObservableTrackBar fully enabled in the LiveBindings designer. The control value name property must be registered using RegisterObservableMember(). This code can go in the same unit which registers the component:
unit VCL.Sample.ObservableTrackbarReg;
interface
procedure Register;
implementation
uses System.Classes, VCL.Sample.ObservableTrackbar, Data.Bind.Components;
procedure Register;
begin
RegisterComponents('LiveBindings Samples', [TObservableTrackBar]);
end;
initialization
Data.Bind.Components.RegisterObservableMember(TArray<TClass>.Create(
TObservableTrackBar),
'Position', 'DFM');
finalization
Data.Bind.Components.UnregisterObservableMember(TArray<TClass>.Create(
TObservableTrackBar));
end.
"Position" is identified as the control value name in two places–in VCL.Sample.ObservableTrackbar .pas with the ObservableMember attribute and in VCL.Sample.ObservableTrackbarReg .pas by calling RegisterObservableMember(). The ObserverbleMember attribute will be used by LiveBindings components to generate expressions. RegisterObserverableMember() will be used at design time to inform the LiveBindings designer.
After installing a package which contains VCL.Sample.ObservableTrackbar and VCL.Sample.ObservableTrackbarReg, TObservableTrackbar can be selected from the component palette. TObservableTrackbar is represented in the LiveBindings designer like this:

ObservableTracker1.Position can be connected to a field using the LiveBindings designer. The following connections include a TEdit so that, when the app is run, you see the value of the field as the thumb is moved:

The default Min and Max values for the TObservableTrackBar are 0 and 10. The data generated by TPrototypeBindSource is out of this range. Modify Min and Max in the object inspector to -100 and 100.
The LiveBindings designer has a command to create the control and connect to a field in one step. This command is available if you right click on a field in the LiveBindings designer.

"Link to new control…" displays a list the controls which have been registered by RegisterObserverableMember(). Scroll down to find TObservableTrackBar.

In addition to linking to fields, TObserverTrackBar can link to component properties. I’ll write about linking simple controls to component properties next time.
Connect with Us