Autor Beitrag
Christian S.
ontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic starofftopic star
Beiträge: 20451
Erhaltene Danke: 2264

Win 10
C# (VS 2019)
BeitragVerfasst: Sa 04.06.05 16:34 
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:
ausblenden 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:
ausblenden 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:
ausblenden 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:
ausblenden 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:
ausblenden 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:
ausblenden 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:
ausblenden 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 user profile iconTino: Topic aus Neue Einträge / Hinweise / etc. verschoben am Do 21.07.2005 um 08:04
Moderiert von user profile iconjasocul: Kleine Anpassung an den StyleGuide
Moderiert von user profile iconjasocul: Beitrag geprüft am 10.05.2006