Entwickler-Ecke

Delphi Language (Object-Pascal) / CLX - Möglichkeit, Eigenschaften von Komponenten abzufragen?


Tranx - So 23.01.11 21:13
Titel: Möglichkeit, Eigenschaften von Komponenten abzufragen?
Besteht eigentlich eine Möglichkeit, bestimmte Eigenschaften einer Komponente (z.B. Text oder checked) abzufragen, um diesen Konstrukt der zig if .. then else if .. else Konstrukte mit dezidierten Typabfragen der Komponenten zu reduzieren? (Möglicherweise Zusammenfassung verschiedener Komponenten oder eben eine Abfrage des Typs:

if Component has checked then ...




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:
38:
39:
40:
41:
42:
43:
44:
45:
46:
47:
48:
49:
50:
51:
52:
53:
54:
55:
56:
57:
58:
59:
60:
61:
62:
63:
64:
65:
66:
67:
68:
69:
70:
71:
72:
73:
74:
75:
76:
77:
78:
79:
procedure TAuswF.TransferFilter(Sender: TObject; wie: integer);
var
  i, j, k: integer;
  Tclb: TChecklistbox;
  TC: TComponent;
begin
  with Mem_Filter.Lines do
  begin
    if wie = exportieren then
    begin
      Clear;
      for i := 0 to AuswF.ComponentCount - 1 do
      begin
        if AuswF.Components[i].Tag = 99 then
        begin
          TC := AuswF.Components[i];
          if AuswF.Components[i] is TCheckbox then
          begin
            Add(BoolToStr(TCheckBox(TC).checked));
          end
          else if TC is TEdit then
          begin
            Add(TEdit(TC).Text);
          end
          else if TC is TMaskEdit then
          begin
            Add(TMaskEdit(TC).Text);
          end
          else if TC is TChecklistBox then
          begin
            Tclb := TChecklistBox(TC);
            for j := 0 to Tclb.Items.Count - 1 do
              Add(BoolToStr(Tclb.checked[j]));
          end
          else if TC is TCombobox then
          begin
            Add(TCombobox(TC).Text);
          end;
        end;
      end;
    end
    else
    begin
      k := 0;
      for i := 0 to AuswF.ComponentCount - 1 do
      begin
        TC := AuswF.Components[i];
        if TC.Tag = 99 then
        begin
          if TC is TCheckbox then
          begin
            TCheckBox(TC).checked := StrToBool(Strings[_inc(k)]);
          end
          else if TC is TEdit then
          begin
            TEdit(TC).Text := Strings[_inc(k)];
          end
          else if TC is TMaskEdit then
          begin
            TMaskEdit(TC).Text := Strings[_inc(k)];
          end
          else if TC is TChecklistBox then
          begin
            Tclb := TChecklistBox(TC);
            for j := 0 to Tclb.Items.Count - 1 do
            begin
              Tclb.checked[j] := StrToBool(Strings[_inc(k)]);
            end;
          end
          else if TC is TCombobox then
          begin
            TCombobox(TC).Text := Strings[_inc(k)];
          end;
        end;
      end;
      Auswaehlen(Sender);  // diese Funktion soll die gewählten Optionen umsetzen (Auswahl der Datensätze)
    end;
  end;
end;


jaenicke - So 23.01.11 21:18

Es gibt GetPropInfo, SetPropValue, SetStringProp, SetInt64Prop, ... usw. (hoffe hab mich richtig erinnert an die Namen^^), alles über die RTTI.


BenBE - So 23.01.11 21:36

Es gibt aber auch, die i.d.R. wesentlich bessere Möglichkeit, sein Software-Konzept entsprechend anzupassen. Eingabe-Komponenten gehören nicht in die Verarbeitungslogik-Schicht des Programmes.


Tranx - So 23.01.11 21:44

Danke für die Infos, doch ich denke, dann werde ich wohl nicht um solche Konstrukte herumkommen. War auch nur eine Frage, ob es einfach ging.

//Edit: Entschuldige, Benbe, aber DEinen Satz verstehe ich nicht so ganz. Diese von mir aufgeführte Prozedur füllt aus einer Textdatei die Komponenten eines Formulars, damit ich nach bestimmten Kriterien Auswahloptionen sichern und wieder zurückladen kann. Ich weiß nicht so recht, was daran verkehrt sein soll, dies über die Abfrage der Komponentenliste zu realisieren?

Etwas nervig ist bloß, dass jede Komponentenklasse (TEDIT, TCHECKBOX...) einzeln bearbeitet werden muss. Ansonsten funktioniert das ganz gut.


delfiphan - So 23.01.11 21:47

Was du vermutlich wissen willst: .Text kannst du über is TControl herausfinden.

Was ich meinte ist das Design. Das Problem ist, dass deine Methode einfach alles macht und total proprietär ist. Sie ist nicht in sich geschlossen sondern greift auf hardcodete GUI-Klassen zu (z.B. Mem_Filter). Daher ist die Methode nicht wiederverwendbar und auch nicht testbar (im Sinne eines Unit-Tests). Du kannst schon mal das Speichern und Laden trennen; du könntest die Logik, die Daten einer Komponente ausliest, rauslösen; du kannst die Methode aus der Form nehmen und in eine separate Klasse tun. Wenn du weiter gehen willst, kannst du die Serialisierung/Deserialisierung generisch machen und die Vorschrift, wie jede Klasse zu serialisieren/deserialisieren ist separieren. Der Export/Import könnte über einen Formatter gehen, sodass man wahlweise z.B. auch in ein XML exportieren kann, ohne den Rest des Codes anzufassen. Und und und. Übertreiben muss man's natürlich auch nicht.


Tranx - So 23.01.11 21:57

Entschuldige, Delphiphan. Aber Deinen Satz verstehe ich auch nicht so ganz. Ich will - wie oben erklärt - eine Sammlung von Optionen zur Auswahl von Daten aus einer Datenbank gezielt zu speichern und wieder laden zu können. Ich weiß0 nicht, was ich da so wild "hardcode" und Annahmen treffe. Die entsprechenden Komponenten, welche gespeichert werden sollen, habe ich mit dem Tag 99 gekennzeichnet. Alle anderen Komponenten werden nciht berücksichtigt. Das Formular ist ein einfaches Formular, bei dem Checkboxen, Editfelder und ähnliche Komponenten besitzt.