Autor Beitrag
OlafSt
ontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic starofftopic star
Beiträge: 465
Erhaltene Danke: 92

Win7, Win81, Win10
Tokyo, VS2017
BeitragVerfasst: Do 13.02.20 16:54 
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:

ausblenden Delphi-Quelltext
1:
2:
3:
type
   ASHSerializerAttribute = class(TCustomAttribute)
   end;


Mit diesem Attribut statte ich nun die spezifischen Controls meines Formulars aus:

ausblenden 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
    { Private-Deklarationen }
  public
    { Public-Deklarationen }
  end;


Im ButtonClick lasse ich dann serialisieren:
ausblenden 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:
ausblenden 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
     { Einen neuen Rtti-Kontext erstellen }
     LContext := TRttiContext.Create;

     { Typinformationen für den Typ TSomeType extrahieren }
     LType := LContext.GetType(TheClass.ClassInfo);
     { Nach dem benutzerdefinierten Attribut suchen und Verarbeitung ausführen }
     LP:=LType.GetAttributes();
     for LAttr in LP do
     begin
          if LAttr is ASHSerializerAttribute then
          begin
               MessageDlg('Gotcha !', mtInformation,[mbOK],0);
          end;
     end;
     { Kontext freigeben }
     LContext.Free;
end;


Compiliert alles, läuft alles. Nur kommt nie ein "Gotcha !" hoch.

Wo liegt mein Denkfehler ?

_________________
Lies, was da steht. Denk dann drüber nach. Dann erst fragen.
jaenicke
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starofftopic star
Beiträge: 18761
Erhaltene Danke: 1640

W10 x64 (Chrome, IE11)
Delphi 10.2 Ent, Oxygene, C# (VS 2015), JS/HTML, Java (NB), PHP, Lazarus
BeitragVerfasst: Do 13.02.20 18:02 
Nicht die Klasseninstanz innerhalb der Eigenschaft, also die Controls, haben das Attribut, sondern die Eigenschaften CheckBox1 und Button1! Du musst also durch die Properties 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.