使用 TPrototypeBindSource 自动更新对象中的属性
Using TPrototypeBindSource to automatically update properties in an object
我正在尝试使用实时绑定来更新我的(非组件)对象的属性。我有一个 TPrototypeBindSource,我用它来将组件绑定到我的对象字段,并在 运行 时间使用 TObjectBindSourceAdapter。如果在编辑组件的 onchange 事件中调用 MyPrototypeBindSource.Refresh
,我可以让它工作,但是有没有办法让它自动发生,而不需要为我的表单上的每个组件设置 onchange 事件?
虽然有 TPrototypeBindSource.AutoPost
,我 suspect 来处理自动 post 控制数据到数据对象,但它没有……好好看看源代码,这个属性 只影响内部数据生成器。
似乎是,我们必须在创建适配器时手动设置此 属性(因为我们就在此时我们将设置 AutoEdit
):
procedure TForm1.PrototypeBindSource1CreateAdapter( Sender: TObject; var ABindSourceAdapter: TBindSourceAdapter );
begin
FPerson := TPerson.Create;
ABindSourceAdapter := TObjectBindSourceAdapter<TPerson>.Create( Self, FPerson );
ABindSourceAdapter.AutoEdit := True;
ABindSourceAdapter.AutoPost := True;
end;
每次你 离开 一个 TEdit
但一个 TCheckBox
将立即 post 数据。
要更改此设置,只需使用 published
方法
procedure TForm1.ControlChanged( Sender: TObject );
begin
if Sender is TComponent
then
TLinkObservers.ControlChanged( Sender as TComponent );
end;
并将其分配给每个需要的控件(例如TEdit.OnChange
)以立即将数据获取到数据对象。
这里一网打尽
type
TPerson = class
private
FFirstname: string;
FLastname: string;
FActive: Boolean;
public
function ToString: string; override;
property Active: Boolean read FActive write FActive;
property Firstname: string read FFirstname write FFirstname;
property Lastname: string read FLastname write FLastname;
end;
TForm1 = class( TForm )
PersonSource: TPrototypeBindSource; { OnCreateAdapter -> PersonSourceCreateAdapter }
Edit1: TEdit; { OnChange -> ControlChanged }
Edit2: TEdit; { OnChange -> ControlChanged }
BindingsList1: TBindingsList;
LinkControlToField1: TLinkControlToField;
LinkControlToField2: TLinkControlToField;
Label1: TLabel;
ApplicationEvents1: TApplicationEvents; { OnIdle -> ApplicationEvents1Idle }
CheckBox1: TCheckBox;
LinkControlToField3: TLinkControlToField;
procedure PersonSourceCreateAdapter( Sender: TObject; var ABindSourceAdapter: TBindSourceAdapter );
procedure ApplicationEvents1Idle( Sender: TObject; var Done: Boolean );
private
FPerson: TPerson;
published
procedure ControlChanged( Sender: TObject );
end;
var
Form1: TForm1;
implementation
{$R *.dfm}
procedure TForm1.ApplicationEvents1Idle( Sender: TObject; var Done: Boolean );
begin
// just for checking then object data
Label1.Caption := FPerson.ToString;
end;
procedure TForm1.ControlChanged( Sender: TObject );
begin
if Sender is TComponent
then
TLinkObservers.ControlChanged( Sender as TComponent );
end;
procedure TForm1.PersonSourceCreateAdapter( Sender: TObject; var ABindSourceAdapter: TBindSourceAdapter );
begin
FPerson := TPerson.Create;
ABindSourceAdapter := TObjectBindSourceAdapter<TPerson>.Create( Self, FPerson );
ABindSourceAdapter.AutoEdit := True;
ABindSourceAdapter.AutoPost := True;
end;
{ TPerson }
function TPerson.ToString: string;
begin
Result := FLastname + ', ' + FFirstname + ' ' + BoolToStr( FActive );
end;
LiveBindings:
Active : ftBoolean -> CheckBox1/CheckedState(Self)
Firstname : ftString -> Edit1/Text
Lastname : ftString -> Edit2/Text
如果您不喜欢将 ControlChanged
方法分配给所有控件,您可以通过调用 TPrototypeBindSource.Post
强制 TPrototypeBindSource
到 post 数据。但是你必须先检查它是否处于编辑模式:
if PersonSource.Editing
then
PersonSource.Post;
每当您需要 posted 数据时调用它...如果在任何时候只需在 TApplicationEvents.OnIdle
.
内调用它
我正在尝试使用实时绑定来更新我的(非组件)对象的属性。我有一个 TPrototypeBindSource,我用它来将组件绑定到我的对象字段,并在 运行 时间使用 TObjectBindSourceAdapter。如果在编辑组件的 onchange 事件中调用 MyPrototypeBindSource.Refresh
,我可以让它工作,但是有没有办法让它自动发生,而不需要为我的表单上的每个组件设置 onchange 事件?
虽然有 TPrototypeBindSource.AutoPost
,我 suspect 来处理自动 post 控制数据到数据对象,但它没有……好好看看源代码,这个属性 只影响内部数据生成器。
似乎是,我们必须在创建适配器时手动设置此 属性(因为我们就在此时我们将设置 AutoEdit
):
procedure TForm1.PrototypeBindSource1CreateAdapter( Sender: TObject; var ABindSourceAdapter: TBindSourceAdapter );
begin
FPerson := TPerson.Create;
ABindSourceAdapter := TObjectBindSourceAdapter<TPerson>.Create( Self, FPerson );
ABindSourceAdapter.AutoEdit := True;
ABindSourceAdapter.AutoPost := True;
end;
每次你 离开 一个 TEdit
但一个 TCheckBox
将立即 post 数据。
要更改此设置,只需使用 published
方法
procedure TForm1.ControlChanged( Sender: TObject );
begin
if Sender is TComponent
then
TLinkObservers.ControlChanged( Sender as TComponent );
end;
并将其分配给每个需要的控件(例如TEdit.OnChange
)以立即将数据获取到数据对象。
这里一网打尽
type
TPerson = class
private
FFirstname: string;
FLastname: string;
FActive: Boolean;
public
function ToString: string; override;
property Active: Boolean read FActive write FActive;
property Firstname: string read FFirstname write FFirstname;
property Lastname: string read FLastname write FLastname;
end;
TForm1 = class( TForm )
PersonSource: TPrototypeBindSource; { OnCreateAdapter -> PersonSourceCreateAdapter }
Edit1: TEdit; { OnChange -> ControlChanged }
Edit2: TEdit; { OnChange -> ControlChanged }
BindingsList1: TBindingsList;
LinkControlToField1: TLinkControlToField;
LinkControlToField2: TLinkControlToField;
Label1: TLabel;
ApplicationEvents1: TApplicationEvents; { OnIdle -> ApplicationEvents1Idle }
CheckBox1: TCheckBox;
LinkControlToField3: TLinkControlToField;
procedure PersonSourceCreateAdapter( Sender: TObject; var ABindSourceAdapter: TBindSourceAdapter );
procedure ApplicationEvents1Idle( Sender: TObject; var Done: Boolean );
private
FPerson: TPerson;
published
procedure ControlChanged( Sender: TObject );
end;
var
Form1: TForm1;
implementation
{$R *.dfm}
procedure TForm1.ApplicationEvents1Idle( Sender: TObject; var Done: Boolean );
begin
// just for checking then object data
Label1.Caption := FPerson.ToString;
end;
procedure TForm1.ControlChanged( Sender: TObject );
begin
if Sender is TComponent
then
TLinkObservers.ControlChanged( Sender as TComponent );
end;
procedure TForm1.PersonSourceCreateAdapter( Sender: TObject; var ABindSourceAdapter: TBindSourceAdapter );
begin
FPerson := TPerson.Create;
ABindSourceAdapter := TObjectBindSourceAdapter<TPerson>.Create( Self, FPerson );
ABindSourceAdapter.AutoEdit := True;
ABindSourceAdapter.AutoPost := True;
end;
{ TPerson }
function TPerson.ToString: string;
begin
Result := FLastname + ', ' + FFirstname + ' ' + BoolToStr( FActive );
end;
LiveBindings:
Active : ftBoolean -> CheckBox1/CheckedState(Self) Firstname : ftString -> Edit1/Text Lastname : ftString -> Edit2/Text
如果您不喜欢将 ControlChanged
方法分配给所有控件,您可以通过调用 TPrototypeBindSource.Post
强制 TPrototypeBindSource
到 post 数据。但是你必须先检查它是否处于编辑模式:
if PersonSource.Editing
then
PersonSource.Post;
每当您需要 posted 数据时调用它...如果在任何时候只需在 TApplicationEvents.OnIdle
.