Arrays aus Komponenten
Will man viele Komponenten gleicher Art in seinem Programm verwenden (also z.B. 20 Editfelder), so bietet es sich an, diese nicht zur Designzeit zu platzieren, sondern sie zur Laufzeit zu erzeugen und dann effektiv zu verwalten. Zwingend notwendig wird ein solches Vorgehen, sobald die Anzahl der Komponenten zur Laufzeit bestimmt wird.
Zur effektiven Verwaltung bietet sich ein (dynamisches) Array, in welchem man die Komponenten ablegt. Am Beispiel der Editfelder sieht dies so aus:
Delphi-Quelltext
1: 2: 3: 4: 5: 6:
| type TForm1 = class(TForm) public private EditsArray: Array of TEdit; end; |
Zur Laufzeit müssen die Editfelder erzeugt werden:
Delphi-Quelltext
1: 2: 3: 4: 5: 6: 7: 8: 9: 10:
| procedure TForm1.FormCreate(Sender: TObject); var i : Integer; begin SetLength(EditsArray, 20); for i:=0 to High(EditsArray) do begin EditsArray[i] := TEdit.Create(self); end; end; |
Hier wird einfach die Länge des Arrays festgesetzt und dann die einzelnen Elemente des Arrays (also die Editfelder) erzeugt. Der Parameter im Konstruktor verweist dabei auf die Form, das heißt, der
Owner der Editfelder ist Form. Damit werden die Editfelder freigegeben, sobald die Form freigegeben wird, der Programmierer muss sich darum nicht mehr kümmern. Auch ist damit die Form für das Laden und Speichenr der
published-Eigenschaften der Editfelder zuständig.
Das reicht jedoch noch nicht. Das Zuweisen eines Owners führt nicht zur Anzeige des Elementes auf dem Owner. Der Owner ist lediglich für die zwei oben angegeben (internen) Dinge zuständig. Um festzulegen, wo das Element angezeigt werden soll, muss der so genannte
parent gesetzt werden. In diesem Fall ist auch die Form. Zusammen mit dem Setzen einiger weiterer Eigenschaften, die sich von selbt erklären sollten, sieht obige Prozedur dann so aus:
Delphi-Quelltext
1: 2: 3: 4: 5: 6: 7: 8: 9: 10: 11: 12: 13: 14: 15: 16: 17: 18: 19:
| procedure TForm1.FormCreate(Sender: TObject); var i : Integer; myEdit : TEdit; begin SetLength(EditsArray, 20); for i:=0 to High(EditsArray) do begin EditsArray[i] := TEdit.Create(self); with EditsArray[i] do begin parent := self; left := 10; top := i * 25; name := 'edit'+IntToStr(i); text := ''; end; end; end; |
Das setzen der Eigenschaft
name macht es übrigens möglich, ein Editfeld per
FindComponent zu finden. Diese Funktion geht alle Komponenten, welche die Form als Owner haben durch (die werden übrigens in einer
TList verwaltet, könnte man in unserem Beispiel auch machen) und liefert die Komponente zurück, welche den entsprechenden Namen hat.
Sind wir damit fertig? Nein! Denn was braucht man öfter bei einer Komponente als ihre Ereignisse? Und die haben wir bisher sträflich vernachlässigt! Im folgenden soll demonstriert werden, wie man allen Editfelder dasselbe Ereignis zuweist und in diesem dann zwischen den Editfeldern differenziert.
Ein Ereignis ist ansich auch nichts anderes als eine Prozedur, welche zu einem bestimmten Zeitpunkt aufgerufen wird. So ist das
TNotifyEvent beispielsweise folgendermaßen deklariert:
Delphi-Quelltext
1: 2:
| type TNotifyEvent = procedure(sender : TObject) of object; |
Eine solche Prozedur legen wir nun an, als Member von TForm1, da wir ja eine Methode brauchen:
Delphi-Quelltext
1: 2: 3: 4: 5: 6: 7:
| type TForm1 = class(TForm) public private procedure editEvent(sender : TObject); end; |
Wie oben bereits erwähnt, soll in dieser Prozedur differenziert werden, von welchem Editfeld sie ausgelöst wurde. Dies geschieht über den Parameter
sender, welcher das entsprechende Editfeld enthält:
Delphi-Quelltext
1: 2: 3: 4: 5:
| procedure TForm1.editEvent(sender : TObject); begin if sender is TEdit then ShowMessage(TEdit(sender).Text); end; |
Nun muss den Editfeldern nur noch mitgeteilt werden, dass sie auch diese Methode ausführen sollen, wenn ein Ereignis eintritt. In diesem Beispiel wollen wir das
OnExit-Ereignis dazu heranziehen:
Delphi-Quelltext
1: 2: 3: 4: 5: 6: 7:
| parent := self; left := 10; top := i * 25; name := 'edit'+IntToStr(i); text := ''; OnExit := editEvent; |
Im Zusammenhang mit Komponentenarrays nützlich kann die Eigenschaft
Tag einer jeden Komponente sein. In ihr kann der Programmierer einen Integer sein Wahl speichern, was natürlich auch der Pointer zu einer Datenstruktur oder einem Objekt sein kann, die oder das man mit der Komponente verbinden möchte. In unserem Fall könnte man z.B. den Index der Komponente in unserem Array darin speichern, um den Zugriff zu vereinfachen.
Diesen Beitrag gibt es auch
HTML-Dokument auf meiner Homepage.
Moderiert von Tino: Topic aus Neue Einträge / Hinweise / etc. verschoben am Do 21.07.2005 um 08:04
Moderiert von jasocul: Kleine Anpassung an den StyleGuide
Moderiert von jasocul: Beitrag geprüft am 10.05.2006