Stocker une chaîne (ou un objet) avec une chaîne dans un ListBox ou ComboBox

TListBox et TComboBox de Delphi affichent une liste d'éléments - des chaînes dans une liste "sélectionnable". TListBox affiche une liste déroulante, la TComboBox affiche une liste déroulante.

Une propriété commune à tous les contrôles ci-dessus est le Articles propriété. Les éléments définissent une liste de chaînes qui apparaîtra dans le contrôle à l'utilisateur. Au moment du design, lorsque vous double-cliquez sur la propriété Items, l '"éditeur de liste de chaînes" vous permet de spécifier des éléments de chaîne. La propriété Items est en fait un descendant de type TStrings.

Deux chaînes par élément dans une ListBox?

Il existe des situations où vous souhaitez afficher une liste de chaînes pour l'utilisateur, par exemple dans le contrôle de zone de liste, mais également un moyen de stocker une autre chaîne supplémentaire le long de celle affichée à l'utilisateur.

De plus, vous voudrez peut-être stocker / attacher plus qu'une simple chaîne "ordinaire" à la chaîne, vous voudrez peut-être attacher un objet à l'élément (chaîne).

ListBox.Items - TStrings "connaît" les objets!

Donnez à l'objet TStrings une autre apparence dans le système d'aide. Il y a le Objets propriété qui représente un ensemble d'objets associés à chacune des chaînes de la propriété Strings - où la propriété Strings fait référence aux chaînes réelles de la liste.

Si vous souhaitez affecter une deuxième chaîne (ou un objet) à chaque chaîne de la zone de liste, vous devez remplir la propriété Items au moment de l'exécution.

Bien que vous puissiez utiliser le ListBox.Items.Add méthode pour ajouter des chaînes à la liste, pour associer un objet à chaque chaîne, vous devrez utiliser une autre approche.

le ListBox.Items.AddObject La méthode accepte deux paramètres. Le premier paramètre, "Article" est le texte de l'article. Le deuxième paramètre, "AObject" est l'objet associé à l'élément.

Notez que la zone de liste expose le Ajouter un item méthode qui fait la même chose que Items.AddObject.

Deux chaînes pour une chaîne

Puisque Items.AddObject et AddItem acceptent une variable de type TObject pour leur deuxième paramètre, une ligne comme:

 // erreur de compilation! ListBox1.Items.AddObject ('zarko', 'gajic'); 

entraînera une erreur de compilation: E2010 Types incompatibles: 'TObject' et 'string'.

Vous ne pouvez pas simplement fournir une chaîne pour l'objet car dans Delphi pour Win32, les valeurs de chaîne ne sont pas des objets.

Pour affecter une deuxième chaîne à l'élément de zone de liste, vous devez «transformer» une variable de chaîne en objet - vous avez besoin d'un objet TString personnalisé.

Un entier pour une chaîne

Si la deuxième valeur que vous devez stocker avec l'élément de chaîne est une valeur entière, vous n'avez en fait pas besoin d'une classe TInteger personnalisée.

 ListBox1.AddItem («Zarko Gajic», TObject (1973)); 

La ligne ci-dessus stocke le nombre entier "1973" avec la chaîne "Zarko Gajic" ajoutée.

Un transtypage direct d'un entier vers un objet est effectué ci-dessus. Le paramètre "AObject" est en fait le pointeur (adresse) de 4 octets de l'objet ajouté. Étant donné que dans Win32, un entier occupe 4 octets - une telle conversion en dur est possible.

Pour récupérer l'entier associé à la chaîne, vous devez redéfinir "l'objet" sur la valeur entière:

 // année == 1973 année: = Entier (ListBox1.Items.Objects [ListBox1.Items.IndexOf ('Zarko Gajic')]); 

Un contrôle Delphi pour une chaîne

Pourquoi arrêter ici? Attribuer des chaînes et des entiers à une chaîne dans une zone de liste est, comme vous venez de le constater, un morceau de gâteau.

Étant donné que les contrôles Delphi sont en fait des objets, vous pouvez attacher un contrôle à chaque chaîne affichée dans la zone de liste.

Le code suivant ajoute aux légendes ListBox1 (zone de liste) de tous les contrôles TButton sur un formulaire (placez-le dans le gestionnaire d'événement OnCreate du formulaire) avec la référence à chaque bouton.

 var   idx: entier; commencer   pour idx: = 0 à -1 + ComponentCount faire   commencer     si Composants [idx] est TButton ensuite ListBox1.AddObject (TButton (Composants [idx]). Légende, Composants [idx]);   fin; fin; 

Pour "cliquer" par programme sur le "deuxième" bouton, vous pouvez utiliser l'instruction suivante:

 TButton (ListBox1.Items.Objects [1]). Cliquez sur; 

Je veux affecter mes objets personnalisés à l'élément de chaîne

Dans une situation plus générique, vous ajouteriez des instances (objets) de vos propres classes personnalisées:

 type   TStudent = classe   privé     fName: chaîne; fAnnée: entier;   Publique     propriété Nom : lecture de chaîne fName;     propriété Année: entier lis fYear;     constructeur Créer(const Nom : chaîne; const année: entier);   fin;… constructeur TStudent.Create (const Nom : chaîne; const année: entier); commencer   fName: = nom; fAnnée: = année; fin; -------- commencer   // ajoute deux chaînes / objets -> étudiants à la liste   ListBox1.AddItem ('John', TStudent.Create ('John', 1970)); ListBox1.AddItem («Jack», TStudent.Create («Jack», 1982));   // attrape le premier élève - John   étudiant: = ListBox1.Items.Objects [0] comme TStudent;   // affiche l'année de John   ShowMessage (IntToStr (student.Year)); fin; 

Ce que vous créez, vous devez le libérer

Voici ce que l'aide a à dire sur les objets des descendants de TStrings: l'objet TStrings ne possède pas les objets que vous ajoutez de cette façon. Les objets ajoutés à l'objet TStrings existent toujours même si l'instance TStrings est détruite. Ils doivent être explicitement détruit par l'application.

Lorsque vous ajoutez des objets à des chaînes - des objets que vous créez - vous devez vous assurer de libérer la mémoire occupée, sinon vous aurez une fuite de mémoire

Une procédure personnalisée générique FreeObjects accepte une variable de type TStrings comme seul paramètre. FreeObjects libérera tous les objets associés à un élément de la liste de chaînes. Dans l'exemple ci-dessus, les "étudiants" (classe TStudent) sont attachés à une chaîne dans une zone de liste, lorsque l'application est sur le point d'être fermée (événement principal OnDestroy du formulaire, pour exemple), vous devez libérer la mémoire occupée:

 FreeObjects (ListBox1.Items); 

Remarque: Vous appelez cette procédure uniquement lorsque les objets affectés aux éléments de chaîne ont été créés par vous.