我正在尝试使用实时绑定来更新我的(非组件)对象的属性。我有一个 TPrototypeBindSource,用于将组件绑定到我的对象字段,并在运行时使用 TObjectBindSourceAdapter。如果调用编辑组件的 onchange 事件,我可以让它工作MyPrototypeBindSource.Refresh
,但是有没有办法让它自动发生,而无需为表单上的每个组件设置 onchange 事件?
问问题
1969 次
1 回答
4
虽然TPrototypeBindSource.AutoPost
我怀疑有一个处理将控制数据自动发布到数据对象的方法,但它并没有......仔细查看源代码,这个属性只会影响内部数据生成器。
似乎是,我们必须在创建适配器时手动设置此属性(因为我们此时也将设置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
发布数据。
要改变这一点,只需使用一种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;
活绑定:
活动:ftBoolean -> CheckBox1/CheckedState(Self) 名字:ftString -> Edit1/Text 姓氏:ftString -> Edit2/Text
如果您不喜欢将该方法分配给所有控件,您可以通过调用ControlChanged
来强制发布数据。但是您必须先检查它是否处于编辑模式:TPrototypeBindSource
TPrototypeBindSource.Post
if PersonSource.Editing
then
PersonSource.Post;
每当您需要发布数据时调用它......如果在任何时候只需在TApplicationEvents.OnIdle
.
于 2015-01-30T23:22:11.167 回答