![]() |
Referenzierung u. Serialisierung von Subkomponenten
Hallo zusammen.
Ich baue gerade an ein paar Komponenten herum, die als Erweiterung an schon länger bestehenden Komponenten benutzt werden sollen. Ausgangssituation ist in etwa folgendes:
Delphi-Quellcode:
Alle Komponenten sind per Register in die Palette aufgenommen und lassen sich auf die Forms klicken. Der SubThingOwner TSubThing = Class(TComponent) //Die zu entwickelnde Komponente private FTestString : string; FTestBool : Boolean; published property TestString : String read FTestString write FTestString; property TestBool : Boolean read FTestBool write FTestBool ; End; TSubThingOwner = Class(TComponent) // Eine bestehende Komponente, die das SubThing initialisieren / befüllen soll constructor Create(AOwner : TComponent);override; private FSubThing : TSubThing; published property SubThing : TSubThing read FSubThing write FSubThing; End; TSubThingUser = Class(TComponent) // Eine neue Komponente, die mit dem befüllten Subthing arbeiten soll. private FReferencedSubThing : TSubThing; published property ReferencedSubThing : TSubThing read FReferencedSubThing write FReferencedSubThing; End; erstellt seine Instanz folgendermaßen:
Delphi-Quellcode:
Das Problem ist jetzt, das ich nicht durchblicke, wer das speichern soll. Setze ich SetSubComponent(true) und verknüpfe SubThingUser.ReferencedSubThing
constructor TSubThingOwner.Create(AOwner: TComponent);
begin inherited; FSubThing := TSubThing.Create(self); // FSubThing.SetSubComponent(true); FSubThing.Name:=Self.Name + 'SUB'; end; mit der Instanz, die von SubThingOwner erstellt wurde, landet sowas im DFM:
Delphi-Quellcode:
Da das SetSubComponent eine Eigenschaft des SubThings und nicht der übergeordneten Komponenten setzt, wird das wohl für jeden Verweis auf die Instanz
object TheOwner: TSubThingOwner
SubThing.TestString = 'ABCD' SubThing.TestBool = True ... end object TheUser: TSubThingUser ReferencedSubThing.TestString = 'ABCD' ReferencedSubThing.TestBool = True ... end mehrfach abgelegt und beim Laden erhalte ich "TheUser.ReferencedSubThing.TestString - Ungültiger Pfad für Eigenschaft", was ja auch Sinn macht, da dort beim Laden keine Instanz vorhanden ist. Setze ich SetSubComponent(False), werden die Eigenschaften von SubThing gar nicht mehr gespeichert. Das liegt wohl daran, dass SubThing nicht die Form als Owner hat, so dass es nicht automatisch serialisiert wird. Gespeichert wird dann nur der Name, ohne die Eigenschaften.
Delphi-Quellcode:
Die Form als Owner von SubThing zu nehmen, damit das automatisch serialisiert wird, würde ich wegen den ganzen Zusatzkomponenten im Formulardesigner gerne vermeiden.
object TheOwner: TSubThingOwner
SubThing = TheOwner.SUB ... end object TheUser: TSubThingUser ReferencedSubThing = TheOwner.SUB ... end Wenn es geht, würde ich auch gerne weiter per Referenz auf SubThing arbeiten. Ich schätze mal die Alternative wäre, die Werte per SubThing.Assign hin- und herzugeben, wodurch ich aber zwangsläufig mit mehreren SubThing-Instanzen arbeiten müsste - oder? Insbesondere bei abgeleiteten / geerbten Forms macht das glaube ich Probleme innerhalb des Form-Designers. Gibt es für sowas ein vernünftiges Entwurfsmuster und wenn ja, wonach suche ich da oder bin ich gerade komplett auf dem Holzweg? |
AW: Referenzierung u. Serialisierung von Subkomponenten
So wird das nicht gehen - wie du ja auch selbst bemerkt hast.
1) Das SetSubComponent(true) ist notwendig, damit die Eigenschaften von SubThing gespeichert werden. 2) Eine SubComponent kann nicht referenziert werden. Ausweg: Referenziere den SubThingOwner und füge ein public read-only property hinzu, das die SubThing-Instanz aus dem SubThingOwner holt.
Delphi-Quellcode:
TSubThingUser = Class(TComponent)
private FReferencedSubThingOwner : TSubThingOwner; function GetReferencedSubThing: TSubThing; public property ReferencedSubThing : TSubThing read GetReferencedSubThing; published property ReferencedSubThingOwner : TSubThingOwner read FReferencedSubThingOwner write FReferencedSubThingOwner; End; function TSubThingUser.GetReferencedSubThing: TSubThing; begin if FReferencedSubThingOwner <> nil then begin result := FReferencedSubThingOwner.SubThing; end else begin result := nil; end; end; |
AW: Referenzierung u. Serialisierung von Subkomponenten
Brett ---> Kopf!
Danke erstmal für die Anwort. Das habe ich gerade so ausprobiert und es geht natürlich sofort ... Da ich das SubThing Property gerne sehen und drin rum schreiben würde, habe ich noch ein wenig weiter gebastelt. Variant 1: SubThing ist nicht im PropertyInspector, geht ... das zu sehen wäre aber besser.
Delphi-Quellcode:
Variant 2: SubThing ist im PropertyInspector, es wird aber wieder mehrfach gespeichert, weil per SetSubComponent geschrieben wird.
TSubThingUser = Class(TComponent)
public property ReferencedSubThing : TSubThing read GetReferencedSubThing; published property ReferencedSubThingOwner : TSubThingOwner read FReferencedSubThingOwner write FReferencedSubThingOwner; End;
Delphi-Quellcode:
Variant 3: SubThing ist im PropertyInspector, es wird wegen stored false nicht im User gespeichert, der Owner bekommt die Änderungen aber mit und schreibt sie.
TSubThingUser = Class(TComponent)
published property ReferencedSubThing : TSubThing read GetReferencedSubThing; property ReferencedSubThingOwner : TSubThingOwner read FReferencedSubThingOwner write FReferencedSubThingOwner; End;
Delphi-Quellcode:
TSubThingUser = Class(TComponent)
published property ReferencedSubThing : TSubThing read GetReferencedSubThing stored FALSE; property ReferencedSubThingOwner : TSubThingOwner read FReferencedSubThingOwner write FReferencedSubThingOwner; End; Variante 3 ist das, was ich wollte und scheint erstmal anstandslos zu funktionieren. Die Klärung der Frage, warum es Sinn macht, einem read-only Property - das eigentlich gar nicht schreiben kann, mitteilen zu müssen, dass es nichts schreiben soll, überlasse ich schlaueren Leuten. :D Danke nochmal. |
Alle Zeitangaben in WEZ +1. Es ist jetzt 01:39 Uhr. |
Powered by vBulletin® Copyright ©2000 - 2025, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024-2025 by Thomas Breitkreuz