Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/ios/95.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Delphi livebinding表单中的现有用户对象_Delphi_Livebindings - Fatal编程技术网

Delphi livebinding表单中的现有用户对象

Delphi livebinding表单中的现有用户对象,delphi,livebindings,Delphi,Livebindings,我尝试在VCL窗体上使用livebindings,其中要绑定到窗体上控件的对象作为属性传递给窗体。我使用的是10.1柏林。在对象中传递的属性是普通的: Public Property ProjectObject: TProject Read fProjectObject Write fProjectObject; 我使用DataGeneratorAdapter和AdapterBindSource使用设计器在表单上设置链接 我缺乏理解的地方是OnCreateAdapter方法中的A

我尝试在VCL窗体上使用livebindings,其中要绑定到窗体上控件的对象作为属性传递给窗体。我使用的是10.1柏林。在对象中传递的属性是普通的:

 Public
      Property ProjectObject: TProject Read fProjectObject Write fProjectObject;
我使用DataGeneratorAdapter和AdapterBindSource使用设计器在表单上设置链接

我缺乏理解的地方是OnCreateAdapter方法中的AdapterBindSource。我能找到的所有示例都显示了如何创建一个新的对象来由控件填充,但是我没有找到一种方法来绑定runtinme fProjectObject(传递的对象)

OnCreateAdapter方法中的当前代码是:

ABindSourceAdapter := TObjectBindSourceAdapter<TProject>.Create(Self);
其中ProjEdit是项目编辑表单,ProjectObject是传递项目对象的属性,Proj是要编辑的项目对象。项目对象只需传递到此表单,并在对信息进行任何更改后存储。此对象在传递到此表单进行编辑之前存储在数据库中

如何将livebindings连接到传递的对象


提前感谢您的帮助

我认为可能让您绊倒的是您的ProjectObject需要的不太明显的一点 要在触发
CreateAdapter
事件之前创建。确保 如果发生这种情况,您需要覆盖表单的Create方法并在那里创建ProjectObject

以下对我来说很好:

type

  TPerson = class
  private
    FLastName: String;
    FFirstName: String;
  public
    property FirstName : String read FFirstName write FFirstName;
    property LastName : String read FLastName write FLastName;
  end;

  TForm1 = class(TForm)
    edFieldA: TEdit;
    edFieldB: TEdit;
    BindNavigator1: TBindNavigator;
    PrototypeBindSource1: TPrototypeBindSource;
    BindingsList1: TBindingsList;
    LinkControlToField1: TLinkControlToField;
    LinkControlToField2: TLinkControlToField;
    procedure PrototypeBindSource1CreateAdapter(Sender: TObject; var
        ABindSourceAdapter: TBindSourceAdapter);
  private
  public
    Person : TPerson;
    constructor Create(AOwner : TComponent);  override;
  end;

[...]

constructor TForm1.Create(AOwner: TComponent);
begin
  Person := TPerson.Create;
  Person.FirstName := 'John';
  Person.LastName := 'Smith';
  inherited;
end;

procedure TForm1.PrototypeBindSource1CreateAdapter(Sender: TObject; var
    ABindSourceAdapter: TBindSourceAdapter);
begin
  ABindSourceAdapter := TObjectBindSourceAdapter<TPerson>.Create(Self, Person, False);
end;
如果您想在我的示例中验证这一点,请在单元的初始化部分创建一个TPerson实例,并在表单的
create
构造函数中将Form1.Person分配给它。您可能没有意识到的是,Delphi对象变量实际上是一个指针,因此它可以自由地“指向”对象的现有实例

重要的是将
TObjectBindSourceAdapter
的最后一个参数设置为False,以便适配器不拥有Person对象,否则它将在Person对象(适配器)被销毁时销毁它

顺便说一句,本视频解释了重写表单构造函数的必要性:

他解释说,如果在CreateAdapter事件之前不创建要绑定到的对象,绑定将清除该对象在绑定字段中已有的任何内容。

我建议如下:

第一:在AdapterBindSource的CreateAdapter中,使用以下命令:

procedure TfrmProjectEdit.AdapterBindSource1CreateAdapter(Sender: TObject; var ABindSourceAdapter: TBindSourceAdapter);
begin
  fProjectObject:=TProject.Create;
  ABindSourceAdapter:=TObjectBindSourceAdapter<TProject>.Create(self, fProjectObject, True);
end;
快速解释:AdapterBindSource将拥有fProjectObject,并在释放ABS时释放它。我们只需为fProjectObject分配一个新值,并在setter中刷新ABS


我还没有测试过这段代码,但我认为这应该可以…

对不起,我不清楚。项目对象被传递给表单。如果它是在表单中创建的,则它没有通过项目对象传递给表单的信息。抱歉,现在我感到困惑,因为我不确定“通过项目对象传递给表单的信息”的确切含义。在任何情况下,正如我所说,您的项目对象必须在
CreateAdapter
事件触发之前存在。重写表单的Create构造函数是一种方法。顺便说一句,您正在将TObjectBindSourceAdapter的最终参数设置为False,是吗?我的例子对你不起作用吗?很抱歉让你更加困惑。我编辑了最初的问题,希望能让我的问题更清楚。我确实观看了您的视频,在我的示例中,我没有将最后一个参数设置为TObjectBindSourceAdapter,因为正是在这一点上,我意识到我无法连接传递给表单的项目对象。谢谢你抽出时间来帮助我。我真的很感激。@sysjames:我想你没有领会MartynA的意思。在编辑“ProjEdit.ProjectObject:=Proj;ProjEdit.showmodel;StoreProject(Proj);”时,ProjectObject分配在创建ProjEdit表单后进行,但为时已晚!您需要在OnCreateAdapter出现之前执行此操作。@AlexJames:谢谢。我没有完全理解那一点。但是,我仍然不知道如何将Proj(项目对象)中的信息作为在组件中显示/编辑的对象。我开始认为,在这种情况下,实时绑定不会带来好处。如果我理解,我不能绑定到现有对象,只能绑定到新创建的对象。这是正确的吗?
constructor TForm1.Create(AOwner: TComponent);
begin
  Person := SomeTPersonObjectCreatedAlreadyInOtherCode;
  inherited;
end;
procedure TfrmProjectEdit.AdapterBindSource1CreateAdapter(Sender: TObject; var ABindSourceAdapter: TBindSourceAdapter);
begin
  fProjectObject:=TProject.Create;
  ABindSourceAdapter:=TObjectBindSourceAdapter<TProject>.Create(self, fProjectObject, True);
end;
procedure TfrmProjectEdit.SetProject (aProject: TProject);
begin
  fProjectObject:=aProject;
  AdapterBindSource1.Refresh;
end;