2017-03-05 18 views
1

我想在窗體上將綁定到窗體上的控件的對象的VCL窗體上使用livebindings作爲屬性傳遞給窗體。我正在使用10.1柏林。其中,在對象傳遞的屬性是普通:livebinding在窗體中的現存用戶對象

Public 
     Property ProjectObject: TProject Read fProjectObject Write fProjectObject; 

我已經使用DataGeneratiorAdapter和AdapterBindSource設置使用設計表格上的鏈接。

我缺乏理解的地方在於OnCreateAdapter方法中的AdapterBindSource。我可以找到的所有示例演示如何創建一個新的對象以供控件填充,但我無法找到在runtinme fProjectObject(傳遞的對象)上綁定的方法。

我在OnCreateAdapter方法當前的代碼是:

ABindSourceAdapter := TObjectBindSourceAdapter<TProject>.Create(Self); 

這是可以接受的編譯器,但不允許控制來顯示和更新fProjectObject的屬性。

的顯示這種形式(該項目的編輯形式)的代碼段的一個看起來是這樣的:

ProjEdit.ProjectObject := Proj; 
ProjEdit.ShowModal; 
StoreProject(Proj); 

哪裏ProjEdit是項目編輯表單,ProjectObject就是項目對象傳遞屬性Proj是要編輯的項目對象。項目對象只是簡單地傳遞給這個表單,並在對信息進行任何更改後進行存儲。該對象在傳遞到此表單以供編輯之前存儲在數據庫中。

如何將livebindings連接到傳遞的對象?

在此先感謝您的幫助

回答

1

這裏是我的建議:

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

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; 

快速說明:AdapterBindSource將擁有fProjectObject並在釋放ABS時釋放它。我們只需將一個新值賦給fProjectObject並刷新setter中的ABS。

我還沒有測試過這個代碼 - 但我認爲這應該工作...

+0

它很好用。謝謝。 – SysJames

1

我想這可能絆倒您的事情是,你需要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的實例,並指定Form1.Person它可以簡單地分配到先前存在的對象,如

constructor TForm1.Create(AOwner: TComponent); 
begin 
    Person := SomeTPersonObjectCreatedAlreadyInOtherCode; 
    inherited; 
end; 

在窗體的Create構造函數中。你可能沒有意識到的是,Delphi對象變量實際上是一個指針,所以它可以自由地「指向」對象的現有實例。

重要的是將TObjectBindSourceAdapter的最終參數設置爲False,以便適配器不擁有Person對象,否則它將在銷燬適配器時銷燬Person對象。

順便說一句,要覆蓋窗體的構造需要在這段視頻中解釋道:

https://delphiaball.co.uk/2015/10/19/livebindings-in-vcl-part-2-livebinding-objects/

他解釋說,如果你不創建對象要綁定到CreateAdapter事件之前,綁定將清除對象在綁定字段中已有的任何內容。

+0

對不起,我不清楚。項目對象被傳遞給表單。如果它是在表單中創建的,則它沒有通過項目對象傳遞給表單的信息。 – SysJames

+0

對不起,現在我很困惑,因爲我不確定你的意思是「通過項目對象傳遞給表單的信息」。無論如何,正如我所說的,在CreateAdapter事件觸發之前,您的項目對象必須存在。覆蓋表單的Create構造函數是一種方法。順便說一句,你* *設置TObjectBindSourceAdapter的最終參數爲False,是嗎?我的榜樣不適合你嗎? – MartynA

+0

對不起已添加到混亂。我編輯了原始問題,希望能更清楚地說明我的問題。我沒看過你的視頻,我沒有在我的例子中設置TObjectBindSourceAdapter的最後一個參數,因爲那時我意識到我沒有辦法連接到傳遞給表單的項目對象。感謝您花時間幫助我。對此,我真的非常感激。 – SysJames