2017-03-05 4 views
1

Ich versuche Livebindings auf einem VCL-Formular zu verwenden, in dem das Objekt, das an die Steuerelemente in dem Formular gebunden werden soll, als eine Eigenschaft an das Formular übergeben wird. Ich benutze 10.1 Berlin. Das Grundstück, auf dem in dem Objekt übergeben wird, ist gewöhnlich:Livebinding eines vorhandenen Benutzerobjekts in einem Formular

Public 
     Property ProjectObject: TProject Read fProjectObject Write fProjectObject; 

Ich habe DataGeneratiorAdapter und AdapterBindSource verwendet, um die Verbindungen auf dem Formular einzurichten mit dem Designer.

Wo ich mangelndes Verständnis habe, ist an der AdapterBindSource in der OnCreateAdapter-Methode. Alle Beispiele, die ich finden kann, zeigen, wie ein neues Objekt erstellt wird, das von den Steuerelementen aufgefüllt wird, aber ich finde keine Möglichkeit, an runtinme fProjectObject (das übergebene Objekt) zu binden.

Meine aktuellen Code im OnCreateAdapter Methode ist:

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

die mit dem Compiler akzeptabel ist, aber nicht erlaubt die Steuerung der Eigenschaften in fProjectObject anzuzeigen und zu aktualisieren.

Der eine der Codeabschnitte, die diese Form zeigt (das Projekt bearbeiten Form) sieht wie folgt aus:

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

Wo ProjEdit ist das Projekt bearbeiten Form, ProjectObject ist die Eigenschaft, in dem das Projekt-Objekt übergeben wird und Proj ist das zu bearbeitende Projektobjekt. Das Projektobjekt wird einfach an dieses Formular übergeben und gespeichert, nachdem Änderungen an den Informationen vorgenommen wurden. Dieses Objekt wurde in einer Datenbank gespeichert, bevor es zur Bearbeitung an dieses Formular übergeben wurde.

Wie verbinde ich die Livebindings mit dem übergebenen Objekt?

Vielen Dank im Voraus für Ihre Hilfe denken

Antwort

1

Hier ist, was ich vorschlagen:

Erstens: In dem CreateAdapter der AdapterBindSource folgenden verwenden:

procedure TfrmProjectEdit.AdapterBindSource1CreateAdapter(Sender: TObject; var ABindSourceAdapter: TBindSourceAdapter); 
begin 
    fProjectObject:=TProject.Create; 
    ABindSourceAdapter:=TObjectBindSourceAdapter<TProject>.Create(self, fProjectObject, True); 
end; 

Zweitens: einen Setter für das Projekt Eigenschaft verwenden wie:

procedure TfrmProjectEdit.SetProject (aProject: TProject); 
begin 
    fProjectObject:=aProject; 
    AdapterBindSource1.Refresh; 
end; 

Schnelle Erklärung: Die AdapterBindSource besitzt das fProjectObject und gibt es frei, wenn das ABS freigegeben wird. Wir weisen dem fProjectObject einfach einen neuen Wert zu und aktualisieren das ABS im Setter.

Ich habe diesen Code nicht getestet - aber ich denke, das sollte funktionieren ...

+0

Es funktioniert super. Vielen Dank. – SysJames

1

ich die Sache, die Sie nach oben ausgelöst haben kann das nicht sehr offensichtliche Punkt ist, dass Ihr ProjectObject vor die CreateAdapter Ereignis ausgelöst wird erstellt werden muss. Um sicherzustellen, dass passiert, müssen Sie die Create-Methode Ihres Formulars überschreiben und dort Ihr ProjectObject erstellen.

Folgende funktioniert gut für mich:

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; 

aktualisieren Die Person Objekt auf dem Formular nicht auf dem Formular erstellt werden. Es kann einfach zu einem vorher vorhandenen Objekt zugewiesen werden, wie in

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

Wenn Sie, dass in meinem Beispiel überprüfen mögen, eine Instanz von TPerson im Initialisierungsabschnitt der Einheit erstellen und zuweisen Form1.Person es im Create Konstruktor des Formulars. Die Sache, die Sie vielleicht nicht realisiert haben, ist, dass eine Delphi-Objektvariable tatsächlich ein Zeiger ist, so dass sie auf eine existierende Instanz des Objekts frei "gezeigt" werden kann.

Wichtig ist, den letzten Parameter von TObjectBindSourceAdapter auf False zu setzen, damit der Adapter das Person-Objekt nicht besitzt, andernfalls zerstört es das Person-Objekt, wenn es (der Adapter) zerstört wird.

Btw, die Notwendigkeit des Formulars Konstruktor überschreiben, wird in diesem Video erklärt:

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

Er erklärt, dass, wenn Sie das Objekt nicht erstellen, die Sie vor dem CreateAdapter Ereignis binden möchten, die Bindung löscht alle Inhalte, die das Objekt bereits in den gebundenen Feldern hatte.

+0

Es tut mir leid, ich war nicht klar. Das Projektobjekt wird an das Formular übergeben. Wenn es im Formular erstellt wird, verfügt es nicht über die Informationen, die über das Projektobjekt an das Formular übergeben wurden. – SysJames

+0

Entschuldigung, jetzt bin ich verwirrt, weil ich nicht sicher bin, was genau Sie mit "Informationen, die über das Projektobjekt an das Formular weitergegeben wurden" meinen. In jedem Fall, wie ich schon sagte, muss Ihr Projektobjekt vorhanden sein, bevor das Ereignis 'CreateAdapter' ausgelöst wird. Das Überschreiben des Create-Konstruktors des Formulars ist eine Möglichkeit, das auszuführen. Btw, du * stellst den letzten Parameter von TObjectBindSourceAdapter auf False, ja? Funktioniert mein Beispiel nicht für Sie? – MartynA

+0

Entschuldigung, um die Verwirrung hinzugefügt zu haben. Ich habe die ursprüngliche Frage bearbeitet, um zu verdeutlichen, was mein Problem ist. Ich habe Ihr Video angeschaut, und in meinem Beispiel habe ich den letzten Parameter nicht auf TObjectBindSourceAdapter gesetzt, weil ich zu diesem Zeitpunkt festgestellt habe, dass ich keine Verbindung mit dem Projektobjekt herstellen konnte, das an das Formular übergeben wurde. Danke, dass du dir die Zeit genommen hast, mir zu helfen. Ich schätze es sehr. – SysJames

Verwandte Themen