Entwickler-Ecke
Sonstiges (Delphi) - Problem mit Attributen
OlafSt - Do 13.02.20 17:54
Titel: Problem mit Attributen
Hallo Freunde,
ich pack das mal hier rein, ist zwar grafische Oberfläche, aber irgendwie auch nicht ;)
Ich möchte einen selbstgebauten Serializer erstellen. Dieser soll für einige Controls auf einem Formular genau definierte Properties serialisieren und als XML später wegspeichern. Ich dachte, Attribute wären da eine prima Idee.
Also habe ich ein ganz simples Attribut erstellt:
Delphi-Quelltext
1: 2: 3:
| type ASHSerializerAttribute = class(TCustomAttribute) end; |
Mit diesem Attribut statte ich nun die spezifischen Controls meines Formulars aus:
Delphi-Quelltext
1: 2: 3: 4: 5: 6: 7: 8: 9: 10:
| type TForm1 = class(TForm) [ASHSerializer] CheckBox1: TCheckBox; [ASHSerializer] Button1: TButton; procedure Button1Click(Sender: TObject); private public end; |
Im ButtonClick lasse ich dann serialisieren:
Delphi-Quelltext
1: 2: 3: 4: 5: 6: 7: 8: 9: 10:
| var I: Integer; TC: TComponent; begin for I := 0 to self.ComponentCount-1 do begin TC:=self.Components[i]; SerializeControl(TC); end; end; |
Um an das Attribut zu gelangen:
Delphi-Quelltext
1: 2: 3: 4: 5: 6: 7: 8: 9: 10: 11: 12: 13: 14: 15: 16: 17: 18: 19: 20: 21: 22: 23: 24:
| procedure SerializeControl(TheClass: TObject); var LContext: TRttiContext; LType: TRttiType; LAttr: TCustomAttribute; LP: TArray<TCustomAttribute>; begin LContext := TRttiContext.Create;
LType := LContext.GetType(TheClass.ClassInfo); LP:=LType.GetAttributes(); for LAttr in LP do begin if LAttr is ASHSerializerAttribute then begin MessageDlg('Gotcha !', mtInformation,[mbOK],0); end; end; LContext.Free; end; |
Compiliert alles, läuft alles. Nur kommt nie ein "Gotcha !" hoch.
Wo liegt mein Denkfehler ?
jaenicke - Do 13.02.20 19:02
Nicht die Klasseninstanz innerhalb der Eigenschaft, also die Controls, haben das Attribut, sondern die Eigenschaften CheckBox1 und Button1! Du musst also durch die PropertiesFelder des Formulars iterieren um die Attribute abzufragen.
Du kannst ja beliebige Objekte in die Eigenschaft hineinpacken und auch wieder herausnehmen. Wo sollte die Information über das Attribut also stehen? Das Objekt weiß ja gar nicht, ob es gerade in der Property steht oder nicht. Die Attribute werden beim Kompilieren verarbeitet.
OlafSt - Mo 17.02.20 14:27
Okay, das habe ich nun erfolglos versucht:
Delphi-Quelltext
1: 2: 3: 4: 5: 6: 7: 8: 9: 10: 11: 12: 13: 14: 15: 16: 17: 18: 19: 20: 21: 22: 23: 24: 25: 26: 27: 28: 29: 30: 31: 32: 33: 34: 35: 36: 37:
| procedure SerializeControl(TheClass: TObject); var LContext: TRttiContext; LType: TRttiType; LAttr: TCustomAttribute; LP: TArray<TCustomAttribute>; LProps: TArray<TRttiProperty>; LProp: TRttiProperty; begin LContext := TRttiContext.Create;
LType := LContext.GetType(TheClass.ClassInfo); LProps:=LType.GetProperties(); for LProp in LProps do begin if LProp.Name.Contains('CheckBox') then begin LP:=LProp.GetAttributes(); for LAttr in LP do begin if LAttr is ASHSerializerAttribute then begin MessageDlg('Serializable CheckBox', mtInformation,[mbOK],0); end; end; end; end; LContext.Free; end; |
Der Aufruf wurde umgestellt auf
Serialize(Form1). Eine Checkbox wird allerdings nie gefunden und auch ohne die Contains-Abfrage erreiche ich nie die MessageBox.
Ich bin wohl zu blöd für sowas. Und das nach 25 Jahren Delphi...
jaenicke - Mo 17.02.20 14:34
Entschuldigung, das war mein Fehler. :oops: Das sind ja Felder und nicht Properties.
Mit GetFields statt GetProperties sollte es also genau so gehen wie du es jetzt hast.
OlafSt - Di 18.02.20 10:54
jaenicke hat folgendes geschrieben : |
Entschuldigung, das war mein Fehler. :oops: Das sind ja Felder und nicht Properties. |
*kopfklatsch* Der Schlag ins Leere. Hätte ich auch selbst drauf kommen können, als ich bei "Ltype." verharrte und im CodeCompletion die GetFields-Methode sah.
Ich probiere das heute Nachmittag aus. Wäre so megacool, wenn das funktionieren würde.
Funktioniert genau so, wie ich mir das vorgestellt habe. Vielen Dank,
jaenicke für den Schubser in die richtige Richtung !
Entwickler-Ecke.de based on phpBB
Copyright 2002 - 2011 by Tino Teuber, Copyright 2011 - 2024 by Christian Stelzmann Alle Rechte vorbehalten.
Alle Beiträge stammen von dritten Personen und dürfen geltendes Recht nicht verletzen.
Entwickler-Ecke und die zugehörigen Webseiten distanzieren sich ausdrücklich von Fremdinhalten jeglicher Art!