The adapter components TListBindSourceAdapter and TObjectBindSourceAdapter enable LiveBindings with user defined TObjects.
Here is a user defined TObject for example.
type TContact = class private FFirstName: string; FLastName: string; public constructor Create; overload; constructor Create(const AFirstName, ALastName: string); overload; property FirstName: string read FFirstName write FFirstName; property LastName: string read FLastName write FLastName; end; function LoadContacts: TList<TContact>;
implementation function LoadContacts: TList<TContact>; begin Result := TObjectList<TContact>.Create; // TODO: Load data from file Result.Add(TContact.Create('Adam', 'Barns')); Result.Add(TContact.Create('Chris', 'Decker')); Result.Add(TContact.Create('Emma', 'Fisk')); end;
One way to use TListBindSourceAdapter is to instantiate the adapter at run time. Drop a TAdapterBindSourceAdapter on the form and implement the CreateAdapter event as follows:
mplementation {$R *.dfm} uses ContactsUnit, System.Generics.Collections; procedure TForm1.AdapterBindSource1CreateAdapter(Sender: TObject; var ABindSourceAdapter: TBindSourceAdapter); begin ABindSourceAdapter := TListBindSourceAdapter<TContact>.Create(Self, LoadContacts); end;i
In the LiveBindings designer, we won’t see the fields for TContact because the TContact type is not known at design time.
Drop a TStringGrid on the form and connection the ‘*’ of AdapterBindSource1 to StringGrid1.
A navigator can be added by right clicking AdapterBindSource1 and choosing "Add Navigator".
The grid is populated when the application is run:
A TDataGeneratorAdapter can be used to provide some fields to use at design time. Add fields with the same name as the properties in TContact. Set AdapterBindSource1.Adapter to DataGeneratorAdapter1.
The form shows sample data and the LiveBindings designer shows field names.
To show this data at design time, the TDataGeneratorAdapter fields have FieldType: ftString and Generator: LoremIpsum.
The LiveBindings designer can be used to connect fields to controls.
Note that an easy way to create a TLabeledEdit is to right click on FirstName then choose "Link to new control…".
At runtime, the TListBindSourceAdapter will be used instead of DataGeneratorAdapter1 because of the CreateAdapter event.
Another way to use TListBindSourceAdapter is to register a custom component. Instead of instantiating a TListBindSourceAdapter in the CreateAdapter event, the custom component is dropped from the tool palette. A TDataGeneratorAdapter is not needed.
The minimal code to for a custom adapter looks like this:
unit ContactsAdapter; interface uses ContactsUnit, Data.Bind.ObjectScope, System.Classes, System.Generics.Collections; type TContactsAdapter = class(TListBindSourceAdapter<TContact>) public constructor Create(AOwner: TComponent); override; end; implementation { TContactsAdapter } constructor TContactsAdapter.Create(AOwner: TComponent); begin inherited Create(AOwner); SetList(LoadContacts); end;
To register the custom adapter, you will need to create and register a package which contains the custom adapter component and TContact class. You will also need and a Register method to register the custom component.
unit ContactsAdapterReg; interface procedure Register; implementation uses System.Classes, ContactsAdapter, ContactsAdapter2; procedure Register; begin RegisterComponents('Test', [TContactsAdapter]); end; end.
A complete implementation of a custom adapter publishes properties and methods:
TContactsAdapter2 = class(TListBindSourceAdapter<TContact>) public constructor Create(AOwner: TComponent); override; published property OnBeforeSetList; property OnAfterSetList; property OnListAppend; property OnListDelete; property OnListInsert; property OnCreateItemInstance; property OnInitItemInstance; property Options; property AutoEdit; property BeforeOpen; property AfterOpen; property BeforeClose; property AfterClose; property BeforeInsert; property AfterInsert; property BeforeEdit; property AfterEdit; property BeforePost; property AfterPost; property BeforeCancel; property AfterCancel; property BeforeDelete; property AfterDelete; property BeforeScroll; property AfterScroll; property BeforeRefresh; property AfterRefresh; property BeforeApplyUpdates; property AfterApplyUpdates; property BeforeCancelUpdates; property AfterCancelUpdates; property OnDeleteError; property OnInsertError; property OnEditError; property OnPostError; property OnApplyUpdatesError; property OnCancelUpdatesError; property OnApplyUpdates; property OnCancelUpdates; property OnHasUpdates; end;
TObjectBindSourceAdapter is used instead of TListBindSourceAdapter to bind to a single object, rather than a list of objects.
TObjectBindSourceAdapter is instantiated like this:
procedure TForm1.AdapterBindSource1CreateAdapter(Sender: TObject; var ABindSourceAdapter: TBindSourceAdapter); begin ABindSourceAdapter := TObjectBindSourceAdapter<TContact>.Create(Self, TContact.Create('Adam', 'Barns')); end;
At run time, there is only a single row of data.
Source forge samples
https://radstudiodemos.svn.sourceforge.net/svnroot/radstudiodemos/branches/RadStudio_XE3/LiveBindings/observers
- ContactsAdapterPackage.dpk
- Implements a custom TListBindSourceAdapter component
- ListAdapterEventProject.dpr
- Demonstrates TAdapterBindSource.CreateAdapter event
- ListAdapterComponentProject.dpr
- Demonstrates custom TListBindSourceAdapter component
- Project: CppListAdapterEventProject.dpr
- Cpp project demonstrates TAdapterBindSource.CreateAdapter event







{ 1 } Comments
How i work with composite objects like
TPerson = class
property Name: string;
end;
Tcontract = class
property Owner: TPerson;
end;
Have any example?
Post a Comment