Tutorial: Creating LiveBindings-Enabled Components
Go Up to Database and LiveBindings Tutorials
This tutorial shows how to create components that can be used with LiveBindings. In this tutorial you will enable a custom TTrackBar component that can be used with LiveBindings.
Note that whenever you drop a TTrackBar component on a form, the LiveBindings Designer will display it without a registered property available, as pictured below.
This is because TTrackBar has not been enabled for LiveBindings usage. In order to enable a component for LiveBindings usage, there are two requirements to fulfill:
- The control must implement observer support because LiveBindings depends on observers to subscribe to control notifications.
- Register the control value name (for instance:
Position
for TTrackBar). This control value name is used by LiveBindings components to generate expressions that get and set the control’s value.
A TTrackBar component cannot be modified directly for this behavior, so observer support must be implemented in a descendant class that you will create by following the steps in this tutorial.
Contents
Creating the New Observable TTrackBar Component
We will name the class that will implement the observable trackbar TObservableTrackbar and the unit itself will be called VCL.Sample.ObservableTrackbar.
The following is the interface section of the TObservableTrackbar component.
unit VCL.Sample.ObservableTrackbar;
interface
uses
Vcl.ComCtrls, System.Classes, WinApi.Messages, WinApi.CommCtrl, Vcl.Controls;
type
[ObservableMember('Position')] { identifies the control value name for TObservableTrackbar }
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; { declaration is in System.Classes }
procedure ObserverAdded(const ID: Integer; const Observer: IObserver); override; { declaration is in System.Classes }
end;
Following is the implementation section:
implementation
uses
System.SysUtils;
{ TObservableTrackBar }
function TObservableTrackBar.CanObserve(const ID: Integer): Boolean;
{ Controls which implement observers always override TComponent.CanObserve(const ID: Integer). }
{ This method identifies the type of observers supported by TObservableTrackbar. }
begin
case ID of
TObserverMapping.EditLinkID, { EditLinkID is the observer that is used for control-to-field links }
TObserverMapping.ControlValueID:
Result := True;
else
Result := False;
end;
end;
{ The overrides for CNHscroll and CNVScroll are where TObservableTrackBar calls the
observable interfaces to notify LiveBindings components when the user moves the thumb.
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. }
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;
{ 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;
{ All controls that 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. }
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;
end.
Registering the New Observable TTrackBar Component
To make TObservableTrackBar fully enabled in the LiveBindings Designer, you need to register it. The control value name property must be registered using the RegisterObservableMember() method. This code can go in the same unit that 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;
- in VCL.Sample.ObservableTrackbarReg.pas by calling RegisterObservableMember().
The ObservableMember attribute will be used by LiveBindings components to generate expressions. RegisterObserverableMember() will be used at design time to inform the LiveBindings Designer.
Using the New Observable TTrackBar Component
After installing a package which contains VCL.Sample.ObservableTrackbar.pas and VCL.Sample.ObservableTrackbarReg.pas, TObservableTrackbar can be selected from the component palette. TObservableTrackbar is represented in the LiveBindings Designer like in the picture below:
Now you can connect ObservableTracker1.Position
to a field (or to another object property) using the LiveBindings Designer.
Conclusion
By following this prototype, you can design your own LiveBindings-enabled components in RAD Studio simply by:
- implementing observer support;
- registering the control value name.