In Delphi XE2 LiveBindings, I need to bind a VCL control of any type to a property of any type on an arbitrary (non-component) object. I can do this unidirectionally. But I ne
I've got this working now. I did it all in the designer, but have converted it to mostly code to share it better on SO.
Create a VCL forms project. On the form, drop each of these on the form:
TBindScope TBindingsList TButton TButton TEdit
Rename one of the buttons to btnLoad and the other to btnSave.
Paste this code over your form unit (assuming it is named Form1). Assign the click handlers for the buttons and run it. Click btnLoad to populate the edit box with TPerson object data, edit the text in the edit box to a new value then click btnSave to write it back to the TPerson object.
unit Form1;
interface
uses
Winapi.Windows, Winapi.Messages, System.SysUtils, System.Variants, System.Classes, Vcl.Graphics,
Vcl.Controls, Vcl.Forms, Vcl.Dialogs, Vcl.StdCtrls, System.Rtti,
// LiveBinding units
System.Bindings.Helper, // Contains TBindings class
Data.Bind.EngExt,
Vcl.Bind.DBEngExt,
Data.Bind.Components,
System.Bindings.Outputs;
type
TPerson = class(TObject)
protected
fName: string;
fAge: integer;
procedure SetName(const Value: string);
public
property Name: string read fName write SetName;
property Age: integer read fAge write fAge;
end;
type
TForm1 = class(TForm)
btnLoad: TButton;
btnSave: TButton;
BindScope1: TBindScope;
BindingsList1: TBindingsList;
Edit1: TEdit;
procedure btnLoadClick(Sender: TObject);
procedure btnSaveClick(Sender: TObject);
private
fInitialized: boolean;
fPerson: TPerson;
procedure Initialize;
public
procedure AfterConstruction; override;
procedure BeforeDestruction; override;
end;
var
Form1: TForm1;
implementation
{$R *.dfm}
procedure TForm1.AfterConstruction;
begin
inherited;
Initialize;
end;
procedure TForm1.BeforeDestruction;
begin
fPerson.Free;
inherited;
end;
procedure TForm1.btnLoadClick(Sender: TObject);
begin
fPerson.Name := 'Doogie Howser';
fPerson.Age := 15;
BindScope1.DataObject := fPerson;
end;
procedure TForm1.btnSaveClick(Sender: TObject);
begin
TBindings.Notify(Edit1, '');
// Could also do this:
//BindingsList1.Notify(Edit1, '');
end;
procedure TForm1.Initialize;
var
expression: TBindExpression;
begin
// Create a binding expression.
expression := TBindExpression.Create(self);
expression.ControlComponent := Edit1;
expression.ControlExpression := 'Text'; // The Text property of Edit1 ...
expression.SourceComponent := BindScope1;
expression.SourceExpression := 'Name'; // ... is bound to the Name property of fPerson
expression.Direction := TExpressionDirection.dirBidirectional;
// Add the expression to the bindings list.
expression.BindingsList := BindingsList1;
// Create a Person object.
fPerson := TPerson.Create;
end;
{ TPerson }
procedure TPerson.SetName(const Value: string);
begin
fName := Value;
ShowMessage('Name changed to "'+ Value +'"');
end;
end.