Tutorial: Creating LiveBindings-Enabled Components

From RAD Studio
Jump to: navigation, search

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.

LBTTrackBar1.png

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.

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:

LBTTrackBar2.png

Now you can connect ObservableTracker1.Position to a field (or to another object property) using the LiveBindings Designer.

LBTTrackBar3.png

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.

See Also