AGB  ·  Datenschutz  ·  Impressum  







Anmelden
Nützliche Links
Registrieren

Referenzierung u. Serialisierung von Subkomponenten

Ein Thema von SurelyNot · begonnen am 16. Feb 2015 · letzter Beitrag vom 16. Feb 2015
Antwort Antwort
SurelyNot

Registriert seit: 3. Dez 2013
4 Beiträge
 
#1

Referenzierung u. Serialisierung von Subkomponenten

  Alt 16. Feb 2015, 13:35
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:

  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;
Alle Komponenten sind per Register in die Palette aufgenommen und lassen sich auf die Forms klicken. Der SubThingOwner
erstellt seine Instanz folgendermaßen:

Delphi-Quellcode:
constructor TSubThingOwner.Create(AOwner: TComponent);
begin
  inherited;
  FSubThing := TSubThing.Create(self);
  // FSubThing.SetSubComponent(true);
  FSubThing.Name:=Self.Name + 'SUB';
end;
Das Problem ist jetzt, das ich nicht durchblicke, wer das speichern soll. Setze ich SetSubComponent(true) und verknüpfe SubThingUser.ReferencedSubThing
mit der Instanz, die von SubThingOwner erstellt wurde, landet sowas im DFM:

Delphi-Quellcode:
object TheOwner: TSubThingOwner
  SubThing.TestString = 'ABCD'
  SubThing.TestBool = True
  ...
end
object TheUser: TSubThingUser
  ReferencedSubThing.TestString = 'ABCD'
  ReferencedSubThing.TestBool = True
  ...
end
Da das SetSubComponent eine Eigenschaft des SubThings und nicht der übergeordneten Komponenten setzt, wird das wohl für jeden Verweis auf die Instanz
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:
object TheOwner: TSubThingOwner
  SubThing = TheOwner.SUB
  ...
end
object TheUser: TSubThingUser
  ReferencedSubThing = TheOwner.SUB
  ...
end
Die Form als Owner von SubThing zu nehmen, damit das automatisch serialisiert wird, würde ich wegen den ganzen Zusatzkomponenten im Formulardesigner gerne vermeiden.
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?
  Mit Zitat antworten Zitat
Benutzerbild von Uwe Raabe
Uwe Raabe

Registriert seit: 20. Jan 2006
Ort: Lübbecke
10.934 Beiträge
 
Delphi 12 Athens
 
#2

AW: Referenzierung u. Serialisierung von Subkomponenten

  Alt 16. Feb 2015, 14:43
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;
Uwe Raabe
Certified Delphi Master Developer
Embarcadero MVP
Blog: The Art of Delphi Programming
  Mit Zitat antworten Zitat
SurelyNot

Registriert seit: 3. Dez 2013
4 Beiträge
 
#3

AW: Referenzierung u. Serialisierung von Subkomponenten

  Alt 16. Feb 2015, 15:31
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:
  TSubThingUser = Class(TComponent)
  public
    property ReferencedSubThing : TSubThing read GetReferencedSubThing;
  published
    property ReferencedSubThingOwner : TSubThingOwner read FReferencedSubThingOwner write FReferencedSubThingOwner;
  End;
Variant 2: SubThing ist im PropertyInspector, es wird aber wieder mehrfach gespeichert, weil per SetSubComponent geschrieben wird.
Delphi-Quellcode:
  TSubThingUser = Class(TComponent)
  published
    property ReferencedSubThing : TSubThing read GetReferencedSubThing;
    property ReferencedSubThingOwner : TSubThingOwner read FReferencedSubThingOwner write FReferencedSubThingOwner;
  End;
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.
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.

Danke nochmal.
  Mit Zitat antworten Zitat
Themen-Optionen Thema durchsuchen
Thema durchsuchen:

Erweiterte Suche
Ansicht

Forumregeln

Es ist dir nicht erlaubt, neue Themen zu verfassen.
Es ist dir nicht erlaubt, auf Beiträge zu antworten.
Es ist dir nicht erlaubt, Anhänge hochzuladen.
Es ist dir nicht erlaubt, deine Beiträge zu bearbeiten.

BB-Code ist an.
Smileys sind an.
[IMG] Code ist an.
HTML-Code ist aus.
Trackbacks are an
Pingbacks are an
Refbacks are aus

Gehe zu:

Impressum · AGB · Datenschutz · Nach oben
Alle Zeitangaben in WEZ +1. Es ist jetzt 07:05 Uhr.
Powered by vBulletin® Copyright ©2000 - 2024, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024 by Thomas Breitkreuz