IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)

La création dynamique de composants


précédentsommairesuivant

II. Gérer des composants créés dynamiquement

Créer des composants dynamiquement, c'est bien ; savoir s'en servir, c'est mieux !

C'est pour répondre à cette problématique que j'ai écrit cette 2e page. En effet, nous venons de voir comment créer des composants dynamiquement, mais ils ne sont pas vraiment fonctionnels. Car, avec la méthode que je vous ai donnée, on est confronté à plusieurs problèmes : tous les boutons ont les mêmes propriétés ; ces propriétés ne peuvent plus être changées par la suite ; c'est le même événement qui est exécuté pour chaque bouton.

II-A. Première méthode : enregistrer chaque bouton

Quand j'ai débuté, la première solution a laquelle j'ai pensé, c'est d'utiliser une variable globale (de type TButton). On peut modifier les propriétés de cette variable, ce qui modifiera l'aspect du bouton. Le problème, c'est quand on a créé plusieurs composants : on n'a le pouvoir que sur le dernier. On peut contourner cette limite en créant une variable de type : array of TButton. Ce tableau doit être dynamique (lui aussi !), car on ne sait pas à l'avance le nombre de boutons que l'on créera. Voici un exemple de cette technique :

 
Sélectionnez
var
  ListeBoutons: array of TButton;
  Nombre: integer = 0;

procedure TForm1.Button1Click(Sender: TObject);
begin
  inc(Nombre);
  SetLength(ListeBoutons, Nombre+1);
  ListeBoutons[Nombre] := TButton.Create(self);
  with ListeBoutons[Nombre] do
  begin
    Parent := Self;
    Left := Nombre*20;
    Width := 20;
    Caption := IntToStr(Nombre);
  end;
end;

procedure TForm1.Button2Click(Sender: TObject);
var
  i: Integer;
begin
  for i := 1 to Nombre do
    ListeBoutons[i].Top := ListeBoutons[i].Top + 10;
end;

Quand l'utilisateur appuie sur Button1, on agrandit le tableau d'un élément (qui servira pour le bouton). Puis, on crée simplement le bouton et on modifie ses propriétés. Ainsi chaque bouton est enregistré dans le tableau. Button2 montre comment modifier les propriétés ultérieurement. Il suffit donc de connaître le numéro du bouton pour pouvoir le contrôler.

II-B. Deuxième méthode : rechercher les boutons

Il existe plusieurs fonctions qui permettent d'accéder à un composant quelconque. Il existe notamment la propriété ComponentCount qui renvoie le nombre de composants qu'il y a sur la fiche. Pour accéder à un composant, on utilise Components.

Remarque issue de l'aide de Delphi : « Pratiquement, Components s'utilise avec ComponentCount pour des traitements itératifs. Néanmoins, gardez à l'esprit que la propriété ComponentCount d'un composant correspond au nombre d'éléments de la liste Components de ce composant. La propriété ComponentCount est supérieure d'une unité à l'indice du dernier élément de Components, car l'indice du premier élément est toujours 0 ».

Pour reprendre le même exemple, pour faire descendre les composants de la fiche, on procède comme suit :

 
Sélectionnez
procedure TForm1.Button2Click(Sender: TObject);
var i: Integer;
begin
 for i := 0 to pred(ComponentCount) do
   if Components[i] is TControl then
     with (Components[i] as TControl)do
       Top := Top + 10;
end;

Les TComponents n'ont pas de propriété Top, car certains composants n'ont pas à être affichés. On regarde d'abord si le composant est un TControl (il a donc la propriété Top) et on le considère ensuite ainsi pour modifier sa propriété. De la même façon, on peut savoir si le composant est un TButton. C'est astuce permet le contrôle de tous les composants d'une fiche, quels qu'ils soient.

Cependant, vous remarquerez que, dans ce dernier exemple, tous les boutons sont déplacés, même ceux qui n'ont pas été créés dynamiquement. Il nous faut trouver quelque chose pour les distinguer. Ce peut-être leur position dans la fiche, leur propriété Cpation ou n'importe quoi d'autre. Je vous conseille la propriété Tag, car elle est commune à TOUS les composants, et elle n'influe pas sur le programme. Ainsi, les procédures précédentes deviennent :

 
Sélectionnez
procedure TForm1.Button1Click(Sender: TObject);
begin
  with TButton.Create(self) do begin
    Parent := Self;
    Left := Random(400);
    Top := Random(400);
    Tag := 1;
  end;
end;

procedure TForm1.Button2Click(Sender: TObject);
var i: Integer;
begin
  for i := 0 to pred(ComponentCount) do
    if Components[i].Tag = 1 then
      (Components[i] as TControl).Top := (Components[i]as TControl).Top + 10;
end;

Ici, tous les composants créés dynamiquement ont leur propriété Tag mise à 1. Cette valeur est bien sûr arbitraire, vous pouvez prendre n'importe laquelle. On aurait pu également utiliser la propriété Name du composant, qui permet, elle, de stocker un string.

D'un point de vue théorique, la propriété Tag ne sert à rien. Il est noté dans l'aide : « La propriété Tag n'a pas de rôle prédéfini. Cette propriété est proposée afin de pouvoir stocker une valeur entière ou elle peut être transtypée sur n'importe quelle valeur 32 bits, comme une référence de composant ou un pointeur ». En fait, puisque chaque composant possède cette propriété, elle peut servir à donner une valeur au composant. Cela permet par exemple de repérer les composants, comme on vient de le faire. Elle peut aussi remplacer des variables entières, relatives à un composant. Avec l'habitude, elle peut donc devenir très intéressante. On peut ainsi regrouper des composants par cette propriété.

II-C. Différencier les événements

Hé, oui ! Si vous avez suivi ce cours, vous aurez remarqué que tous les boutons créés font la même chose. Et là encore, il faut différencier les composants. La méthode reste la même : récupérer la propriété Tag (ou Name, ou autre chose) et agir en conséquence.

 
Sélectionnez
procedure TForm1.MaProcedure(Sender: TObject);
begin
  case (Sender as TComponent).Tag of
    1: {instructions...};
    2: {instructions...};
    { autres valeurs ... }
  else
    {instructions par défaut...};
  end;
end;

Ce n'est qu'un exemple… Vous pouvez faire comme bon vous semble. Par exemple, il est possible d'effectuer des calculs en fonction de la valeur Tag et de retourner le résultat. Il est souvent intéressant de numéroter les composants. Pensez à utiliser une variable globale pour cela.


précédentsommairesuivant

Copyright © 2005 Laurent Le Brun. Aucune reproduction, même partielle, ne peut être faite de ce site ni de l'ensemble de son contenu : textes, documents, images, etc. sans l'autorisation expresse de l'auteur. Sinon vous encourez selon la loi jusqu'à trois ans de prison et jusqu'à 300 000 € de dommages et intérêts.