Delphi-PRAXiS
Seite 1 von 2  1 2      

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Algorithmen, Datenstrukturen und Klassendesign (https://www.delphipraxis.net/78-algorithmen-datenstrukturen-und-klassendesign/)
-   -   Delphi Komponente über Namensvarialble ansprechen? (https://www.delphipraxis.net/200896-komponente-ueber-namensvarialble-ansprechen.html)

Daniel L. 4. Jun 2019 20:57

Komponente über Namensvarialble ansprechen?
 
Hi Experten!

Lassen sich Komponenten allgemein über eine Art Namesvariable ansprechen?

Beispiel:
ich hab eine Menge Buttons auf der Form (visuell erstellt).

Delphi-Quellcode:
var btn1, btn2 ... btn10 : TButton;


Nun sollen zur Runtime einige Eigenschaften gesetzt werden.
Normalerweise also:
Delphi-Quellcode:
btn1.caption := 'asdf';
btn1.hint := 'einHint';
btn1.enabled := false:
...
btn2.caption := 'asdf';
btn2.hint := 'einHint';
btn2.enabled := false:
...
Nun suche ich aber nach einer Möglichkeit, das zu verallgemeinern.

Ok, es gibt arrays.
Ich könnte alle Buttons per code erstellen.
Delphi-Quellcode:
var BtnAr : array of TButton;

for i := 1 to 10 do
  begin
    btnAr [i] := TButton.create (self);   
    btnAr [i].caption := 'asdf';       
    ...
  end;
Aber geht es auch anders?

Gibt es also eine Möglichkeit, die visuell erstellten Buttons allgemein mit dem 'btn' - Teil und dem Index anzusprechen?
Mit Objekten ist ja viel möglich...

Daniel

mkinzler 4. Jun 2019 21:01

AW: Komponente über Namensvarialble ansprechen?
 
Wenn Du die Referenzen (z.B. nach dem Erzeugen der Form) in einen Array ablegst oder mit der Form.FindComponent() Krücke

Uwe Raabe 4. Jun 2019 21:04

AW: Komponente über Namensvarialble ansprechen?
 
Zitat:

Zitat von Daniel L. (Beitrag 1433896)
Gibt es also eine Möglichkeit, die visuell erstellten Buttons allgemein mit dem 'btn' - Teil und dem Index anzusprechen?

Zitat:

Zitat von mkinzler (Beitrag 1433898)
oder mit der Form.FindComponent() Krücke

Das wäre dann diese:
Delphi-Quellcode:
var
  btn: TButton;
  I: Integer;
begin
  for I := 1 to <anzahl button> do begin
    btn := FindComponent('btn' + I.ToString) as TButton;
    btn.caption := 'asdf';
    btn.hint := 'einHint';
    btn.enabled := false:
  end;
end;

DieDolly 4. Jun 2019 21:06

AW: Komponente über Namensvarialble ansprechen?
 
Ich hätte auch noch eine Idee.
Alle Buttons die man später ansprechen möchte in eine TList<TButton> stecken. Damit vermeidet man dieses ständige FindComponent.

Daniel L. 4. Jun 2019 21:13

AW: Komponente über Namensvarialble ansprechen?
 
whow - ihr seid schnell :-D

Vielen Dank

haentschman 5. Jun 2019 05:55

AW: Komponente über Namensvarialble ansprechen?
 
Moin...8-)

...einen hätte ich noch. :stupid:

TObjectDictionary<string, TButton> oder TDictionary<string, TButton>
...da kann man die Buttons auch nach dem Namen suchen. :thumb: PS: Um Längen schneller als FindComponent!

Maekkelrajter 6. Jun 2019 12:11

AW: Komponente über Namensvarialble ansprechen?
 
Zitat:

Zitat von mkinzler (Beitrag 1433898)
Wenn Du die Referenzen (z.B. nach dem Erzeugen der Form) in einen Array ablegst oder mit der Form.FindComponent() Krücke

Wieso 'Krücke'?
Die Booleschen Werte aller Checkboxen in einem 'Optionen'-Dialog habe ich in einer 32-Bit Integervariablen gespeichert. Das Setzten der Checkboxen erfolgt folgendermaßen:
Delphi-Quellcode:
  Procedure SetCheckboxes(params: Cardinal);
  var i,len: Integer;
      TC: TCheckbox;
  begin
    len:= (sizeof(params) * 8) - 1;  // Anzahl der Bits -1
    for i:= 0 to len do
    begin
      TC:= FindComponent('CheckBox' + IntToStr(i+1)) as TCheckbox; //checkbox1 ... checkbox32
      IF TC <> NIL Then TC.checked:= params and (1 shl i) <> 0;
    end;
  end;
Das Auslesen der Checkboxen geht entsprechend:

Delphi-Quellcode:
  Procedure ReadCheckboxes(var params: Cardinal);
  var i,len: Integer;
      TC: TCheckbox;
  begin
    params:= 0;                      // Alle Bits löschen
    len:= (sizeof(params) * 8) - 1;  // Anzahl der Bits -1
    for i:= 0 to len do
    begin
      TC:= FindComponent('CheckBox' + IntToStr(i+1)) as TCheckbox; //checkbox1 ... checkbox32
      If (TC <> NIL) and TC.checked Then Params:= Params or (1 shl i);
    end;
  end;
Die Performance ist dabei kein Problem, da das immer nur beim Öffnen bzw. Schließen des Dialogs ausgeführt wird. Wie sähe denn die Alternative z. B. hiermit aus:
Zitat:

Zitat von haentschman (Beitrag 1433912)
TObjectDictionary<string, TButton> oder TDictionary<string, TButton>

Das Dictionary müsste doch erstmal erzeugt und befüllt werden. Wo läge da der Vorteil?

Gruß LP

DieDolly 6. Jun 2019 12:32

AW: Komponente über Namensvarialble ansprechen?
 
Zitat:

Das Dictionary müsste doch erstmal erzeugt und befüllt werden. Wo läge da der Vorteil?
Wenn man später doch mal wieder über die Komponenten gehen möchte, dann erfolgt das mit dem Dictionary wirklich nur über die gewünschten Komponenten. Keine nil Abfragen und schleifen mehr.

Uwe Raabe 6. Jun 2019 12:40

AW: Komponente über Namensvarialble ansprechen?
 
Zitat:

Zitat von DieDolly (Beitrag 1434047)
Wenn man später doch mal wieder über die Komponenten gehen möchte, dann erfolgt das mit dem Dictionary wirklich nur über die gewünschten Komponenten. Keine nil Abfragen und schleifen mehr.

Das tut FindComponent auch gar nicht (mehr). Beim ersten Aufruf wird eine nach Namen sortierte Liste aller Komponenten erzeugt, auf die dann über eine binäre Suche zugegriffen wird. Das mag zwar noch marginal langsamer sein, als ein Zugriff in einem TDictionary, aber das schlägt vermutlich gar nicht ins Gewicht. Man spart sich eben den zusätzlichen Verwaltungsaufwand.

Daniel L. 6. Jun 2019 22:26

AW: Komponente über Namensvarialble ansprechen?
 
Also ich hab jetzt erstmal FindComponent eingebaut.
Sinvoll eingesetzt konnte die Größe des gesamten Quelltextes meines Projektes prompt um 25 % verkleinert werden:-D

Danke nochmal an alle - Daniel


Alle Zeitangaben in WEZ +1. Es ist jetzt 20:44 Uhr.
Seite 1 von 2  1 2      

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