Paires nom / Valeur dans une liste déroulante
Je suis convaincue que cela doit être un problème commun, mais je n'arrive pas à trouver une solution simple...
Je veux utiliser un contrôle zone de liste déroulante avec des paires nom /valeur, car les éléments. ComboBox prend TStrings que ses articles de sorte que doit être fine.
Malheureusement, la méthode de dessin sur un combobox attire des Articles[i] de sorte que vous obtenez Nom=Valeur dans la zone.
J'aimerais que la valeur cachée, afin que je puisse travailler avec la valeur dans le code, mais l'utilisateur voit le nom.
Des Idées?
OriginalL'auteur James Barrass | 2010-06-11
Vous devez vous connecter pour publier un commentaire.
Ensemble
Style
àcsOwnerDrawFixed
et écrireAu final, j'ai juste copié StdCtrls TCustomComboBox.DrawItem et remplacer les éléments appel, C'est seulement 3 lignes de toute façon.
JamesB - l'a déclaré la réponse ci-dessus est plus dans l'avenir. Ce qui se passe quand votre copier/coller le code d'StdCtrls est pas à jour relativement à la base VCL ou les contrôles communs de windows?
L'collé le code de lit ...FillRect... ...TextOut... je me rends compte que de copier et de coller le code n'est pas toujours la meilleure idée, mais le code correspondant à la CLASSIFICATION de vienne n'a, au moins, maintenir consistancy de l'apparence à d'autres Contrôles VCL. Je ne m'inquiète pas trop avec FillRect ou TextOut être imminente obsolète.
OriginalL'auteur Andreas Rejbrand
Si vos valeurs sont des nombres entiers:
Diviser les paires nom /valeur, stocker les noms dans les cordes de la zone de liste déroulante et les valeurs dans les objets correspondants.
De cette façon, vous pouvez continuer à utiliser vos contrôles de manière générique et ont encore de la valeur disponible à travers:
Cette approche peut également être utilisé pour les listes des autres objets. Par exemple, un TObjectList contenant TPerson des instances de l'objet:
et retrouver les TPerson de l'élément sélectionné par:
Mise à jour
Une meilleure façon - et l'un ne dépend pas de les valeurs sont des nombres entiers - est à pré-traiter la Liste, en mettant les valeurs dans une classe simple et ajout d'instances de celle-ci à la Liste des Objets.
Simple étendu RTTI base - classe wrapper:
Si vous utilisez un pré-D2010 version de Delphi, il suffit d'utiliser
string
au lieu de TValue.Pré-traitement de la liste:
Le chargement de la liste dans la zone de liste déroulante est maintenant une simple affectation:
Ne garder à l'esprit que, en interne, cela ne une de céder, de sorte que vous mieux vous assurer que le combo n'a plus accès aux instances de sa liste des objets avant de vous gratuit Liste.
Obtenir le nom et la valeur de la liste:
ou de la zone de liste déroulante:
La même information avec explication plus détaillée peut être trouvée sur mon blog: TL;DR version de Paires Nom /Valeur dans les zones de liste modifiables et proches disparus
OriginalL'auteur Marjan Venema
La zone de liste déroulante d'éléments de texte doit avoir contenu l'affichage de texte. C'est le style propre. Ensuite, utilisez le ItemIndex propriété est la clé de valeurs. Vaincre les propriétés du contrôle pour contenir votre modèle de code ou de la base de données interne des valeurs de clé, est une énorme violation des principes de la programmation orientée objet.
Disons simplement examiner comment quelqu'un va maintenir votre application dans le futur. Vous pouvez revenir à ce code vous-même et de penser, "a quoi je pensais?". Rappelez-vous le "principe de moindre étonnement". Utiliser les choses de la façon dont ils ont été destiné à être utilisé, et vous sauver vous-même et vos collègues de la douleur.
OriginalL'auteur Warren P
Je suis d'accord avec Marjan Venema la solution, car il utilise déjà la prise en charge intégrée pour stocker des objets dans une TStringList.
J'ai aussi traité ce et j'ai d'abord tiré mon propre composant combobox à l'aide d'une version remaniée de la posté la solution ci-dessus avec "csOwnerDrawFixed". J'ai vraiment besoin de stocker un IDENTIFIANT (généralement à partir d'une base de données) avec un texte. L'ID serait caché à l'utilisateur. Je pense que c'est un scénario commun. Le ItemIndex est simplement utilisé pour récupérer des données à partir de la liste, il n'est pas vraiment significatif de la variable, comme dans la posté exemple ci-dessus.
Donc, mon idée était de concaténer les ID avec l'affichage de texte, séparés par un "#" par exemple, et de remplacer DrawItem() de sorte qu'il ne serait que de la peinture le texte avec l'ID dépouillé. J'ai étendu ce pour garder plus d'un ID, sous la forme "Nom#ID;var1;var2" par exemple. "Michael Simons#11;true;M". DrawItem() serait dépouiller de tout ce qui suit #.
Maintenant, c'est bon pour commencer, quand vous avez quelques éléments dans une liste déroulante. Mais lorsque l'on traite avec une liste plus large, le défilement de la liste déroulante fait un usage intensif du PROCESSEUR, comme à chaque élément de tirage, le texte doit être dépouillé.
La deuxième version que j'ai fait utilisé la méthode AddObject. Procédant à des échanges de CPU pour un peu plus de la consommation de mémoire, mais C'est un commerce équitable, parce que les choses ont été beaucoup plus vite.
Texte que voit l'utilisateur est stockée normalement dans la liste déroulante.Les éléments et toutes les autres données sont stockées dans une TStringList associés à chaque élément. Pas besoin de surcharger DrawItem, de sorte que vous pouvez tirer d'eg. TmxFlatComboBox et de garder son look plat.
Voici certaines des fonctions les plus importantes de la dérivée de la composante:
Dans les deux versions, toutes les données (même ID) sont représentés comme des chaînes de caractères, parce que cela rend les choses plus générales, de sorte que quand vous les utilisez, vous devez faire beaucoup de StrToInt et vice versa conversions.
Exemple d'utilisation:
Aussi, un
méthode est utile, afin de récupérer l'index de toute pièce d'identité, mais cette réponse est déjà trop long pour le poster ici.
En utilisant le même principe, vous pouvez également dériver une coutume ListBox ou CheckListBox.
Et existant DB-contrôle généralement interroger la base de données trop souvent et ne sont pas aussi flexibles que les contrôles habituels.
OriginalL'auteur talereader