Dans le post Enum ToString , une méthode est décrite pour utiliser l'attribut personnalisé DescriptionAttribute
comme ceci:
Enum HowNice {
[Description("Really Nice")]
ReallyNice,
[Description("Kinda Nice")]
SortOfNice,
[Description("Not Nice At All")]
NotNice
}
Et puis, vous appelez une fonction GetDescription
, en utilisant une syntaxe comme:
GetDescription<HowNice>(NotNice); // Returns "Not Nice At All"
Mais cela ne m'aide pas vraiment quand je veux simplement remplir un ComboBox avec les valeurs d'une énumération, car je ne peux pas forcer le ComboBox à appelerGetDescription
.
Ce que je veux a les exigences suivantes:
- En train de lire
(HowNice)myComboBox.selectedItem
renverra la valeur sélectionnée comme valeur d'énumération. - L'utilisateur doit voir les chaînes d'affichage conviviales, et pas seulement le nom des valeurs d'énumération. Ainsi, au lieu de voir "
NotNice
", l'utilisateur verrait "Not Nice At All
". - Espérons que la solution nécessitera des modifications minimes du code des énumérations existantes.
Évidemment, je pourrais implémenter une nouvelle classe pour chaque énumération que je crée, et la remplacer ToString()
, mais c'est beaucoup de travail pour chaque énumération, et je préfère éviter cela.
Des idées?
Heck, je vais même jeter un câlin en guise de prime :-)
Réponses:
Vous pouvez écrire un TypeConverter qui lit les attributs spécifiés pour les rechercher dans vos ressources. Ainsi, vous obtiendrez un support multilingue pour les noms d'affichage sans trop de tracas.
Examinez les méthodes ConvertFrom / ConvertTo de TypeConverter et utilisez la réflexion pour lire les attributs de vos champs d' énumération .
la source
ComboBox
a tout ce dont vous avez besoin: laFormattingEnabled
propriété, que vous devez définirtrue
, et l'Format
événement, où vous devrez placer la logique de mise en forme souhaitée. Donc,la source
DataGridComboBoxColumn
cependant. Une chance de le résoudre? Je ne suis pas en mesure de trouver un moyen d'obtenir l' accès auComboBox
duDataGridComboBoxColumn
.Pas! Les énumérations sont des primitives et non des objets d'interface utilisateur - les faire servir l'interface utilisateur dans .ToString () serait plutôt mauvais du point de vue de la conception. Vous essayez de résoudre le mauvais problème ici: le vrai problème est que vous ne voulez pas que Enum.ToString () apparaisse dans la liste déroulante!
Maintenant, c'est un problème très résoluble! Vous créez un objet d'interface utilisateur pour représenter vos éléments de liste déroulante:
Et puis ajoutez simplement des instances de cette classe à la collection Items de votre zone de liste déroulante et définissez ces propriétés:
la source
Dictionary
et ont utilisé les propriétésKey
etValue
commeDisplayMember
etValueMember
.TypeConverter. Je pense que c'est ce que je cherchais. Salut à tous Simon Svensson !
Tout ce que j'ai besoin de changer dans mon énumération actuelle est d'ajouter cette ligne avant leur déclaration.
Une fois que je fais cela, toute énumération sera affichée en utilisant le
DescriptionAttribute
de ses champs.Oh, et le
TypeConverter
serait défini comme ceci:Cela m'aide avec mon cas ComboBox, mais ne remplace évidemment pas le fichier
ToString()
. Je suppose que je vais me contenter de ça en attendant ...la source
[TypeConverter(typeof(EnumToStringUsingDescription))] public enum MyEnum {[Description("Blah")] One}
, essayé de le faireConsole.WriteLine(MyEnum.One)
et il sort toujours comme "One". Avez-vous besoin d'une magie spéciale commeTypeDescriptor.GetConverter(typeof(MyEnum)).ConvertToString(MyEnum.One)
(qui fonctionne bien)?En utilisant votre exemple d'énumération:
Créez une extension:
Ensuite, vous pouvez utiliser quelque chose comme ce qui suit:
Voir: http://www.blackwasp.co.uk/EnumDescription.aspx pour plus d'informations. Le mérite revient à Richrd Carr pour la solution
la source
Vous pouvez créer une structure générique que vous pouvez utiliser pour toutes vos énumérations contenant des descriptions. Avec les conversions implicites vers et depuis la classe, vos variables fonctionnent toujours comme l'énumération, sauf pour la méthode ToString:
Exemple d'utilisation:
la source
Je ne pense pas que vous puissiez le faire sans simplement vous lier à un type différent - du moins, pas de manière pratique. Normalement, même si vous ne pouvez pas contrôler
ToString()
, vous pouvez utiliser aTypeConverter
pour faire un formatage personnalisé - mais IIRCSystem.ComponentModel
ne respecte pas cela pour les énumérations.Vous pourriez vous lier à l'une
string[]
des descriptions ou à quelque chose comme une paire clé / valeur? (description / valeur) - quelque chose comme:Et puis lier à
EnumWrapper<HowNice>.GetValues()
la source
theComboBox.SelectItem
c'est le type deEnumWrapper<T>
, au lieu deT
lui - même. Je pense que Scraimer veutReading (HowNice)myComboBox.selectedItem will return the selected value as the enum value.
.La meilleure façon de faire est de créer un cours.
Je pense que c'est la meilleure façon de procéder.
Lorsqu'il est bourré dans des comboboxes, le joli ToString sera affiché, et le fait que personne ne puisse créer plus d'instances de votre classe en fait essentiellement une énumération.
ps il faudra peut-être quelques légères corrections de syntaxe, je ne suis pas très bon avec C #. (Gars de Java)
la source
private HowNice(String desc) : base(desc) { }
et les champs statiques.Étant donné que vous préférez ne pas créer de classe pour chaque énumération, je vous recommande de créer un dictionnaire de la valeur enum / texte d'affichage et de le lier à la place.
Notez que cela a une dépendance sur les méthodes de la méthode GetDescription dans la publication d'origine.
la source
Impossible de remplacer la ToString () des énumérations en C #. Cependant, vous pouvez utiliser des méthodes d'extension;
Bien sûr, vous devrez faire un appel explicite à la méthode, ie;
Ce n'est pas une bonne solution, avec une instruction switch et tout - mais cela devrait fonctionner et, espérons-le, sans beaucoup de réécritures ...
la source
Suite à la réponse @scraimer, voici une version du convertisseur de type enum-to-string, qui prend également en charge les indicateurs:
Et une méthode d'extension pour l'utiliser:
la source
J'écrirais une classe générique à utiliser avec n'importe quel type. J'ai utilisé quelque chose comme ça dans le passé:
En plus de cela, vous pouvez ajouter une "méthode de fabrique" statique pour créer une liste d'éléments de combobox avec un type enum (à peu près identique à la méthode GetDescriptions que vous avez là). Cela vous éviterait d'avoir à implémenter une entité pour chaque type d'énumération, et fournirait également un endroit agréable / logique pour la méthode d'assistance "GetDescriptions" (personnellement, je l'appellerais FromEnum (T obj) ...
la source
Créez une collection qui contient ce dont vous avez besoin (comme des objets simples contenant une
Value
propriété contenant laHowNice
valeur d'énumération et uneDescription
propriété contenantGetDescription<HowNice>(Value)
et reliez le combo à cette collection.Un peu comme ça:
lorsque vous avez une classe de collection comme celle-ci:
Comme vous pouvez le voir, cette collection est facilement personnalisable avec lambda pour sélectionner un sous-ensemble de votre énumérateur et / ou implémenter une mise en forme personnalisée au
string
lieu d'utiliser laGetDescription<T>(x)
fonction que vous mentionnez.la source
Vous pouvez utiliser PostSharp pour cibler Enum.ToString et ajouter tout le code souhaité. Cela ne nécessite aucune modification de code.
la source
Ce dont vous avez besoin est de transformer une énumération en ReadonlyCollection et de lier la collection à la liste déroulante (ou à tout contrôle activé par paire clé-valeur)
Tout d'abord, vous avez besoin d'une classe pour contenir les éléments de la liste. Puisque tout ce dont vous avez besoin est la paire int / string, je suggère d'utiliser une interface et un combo de classe de base afin que vous puissiez implémenter la fonctionnalité dans n'importe quel objet de votre choix:
Voici l'interface et un exemple de classe qui l'implémente.Notez que la classe 'Key est fortement typée dans Enum, et que les propriétés IValueDescritionItem sont implémentées explicitement (donc la classe peut avoir n'importe quelles propriétés et vous pouvez CHOISIR celles qui implémentent le Paire clé / valeur.
Maintenant, la classe EnumToReadOnlyCollection:
Donc, tout ce dont vous avez besoin dans votre code est:
N'oubliez pas que votre collection est tapée avec MyItem, donc la valeur de la zone de liste déroulante doit renvoyer une valeur d'énumération si vous vous liez à la propriété appropriée.
J'ai ajouté la propriété T this [Enum t] pour rendre la collection encore plus utile qu'un simple consommable combo, par exemple textBox1.Text = enumcol [HowNice.ReallyNice] .NicenessDescription;
Vous pouvez bien sûr choisir de transformer MyItem en une classe Key / Value utilisée uniquement pour cette puprose en sautant efficacement MyItem dans les arguments de type de EnumToReadnlyCollection, mais vous seriez alors obligé d'utiliser int pour la clé (ce qui signifie obtenir combobox1. retournerait int et non le type enum). Vous contourner ce problème si vous créez une classe KeyValueItem pour remplacer MyItem et ainsi de suite ...
la source
Désolé d'avoir récupéré ce vieux fil de discussion.
J'irais de la manière suivante pour localiser enum, car il peut afficher des valeurs significatives et localisées à l'utilisateur, pas seulement une description, via un champ de texte de liste déroulante dans cet exemple.
Tout d'abord, je crée une méthode simple appelée OwToStringByCulture pour obtenir des chaînes localisées à partir d'un fichier de ressources globales, dans cet exemple, il s'agit de BiBongNet.resx dans le dossier App_GlobalResources. Dans ce fichier de ressources, assurez-vous que toutes les chaînes sont identiques aux valeurs de l'énumération (ReallyNice, SortOfNice, NotNice). Dans cette méthode, je passe le paramètre: resourceClassName qui est généralement le nom du fichier de ressources.
Ensuite, je crée une méthode statique pour remplir une liste déroulante avec enum comme source de données, appelée OwFillDataWithEnum. Cette méthode peut être utilisée avec n'importe quelle énumération plus tard.
Ensuite, dans la page avec une liste déroulante appelée DropDownList1, j'ai défini dans le Page Load ce qui suit juste une simple ligne de code pour remplir l'énumération de la liste déroulante.
C'est tout. Je pense qu'avec quelques méthodes simples comme celles-ci, vous pouvez remplir n'importe quel contrôle de liste avec n'importe quelle énumération, avec non seulement des valeurs descriptives, mais un texte localisé à afficher. Vous pouvez utiliser toutes ces méthodes comme méthodes d'extension pour une meilleure utilisation.
J'espère que cette aide. Partagez pour être partagé!
Voici les méthodes:
la source
Pour résoudre ce problème, vous devez utiliser une méthode d'extension et un tableau de chaînes comme ceci:
Code simple et décodage rapide.
la source
J'ai essayé cette approche et cela a fonctionné pour moi.
J'ai créé une classe wrapper pour les enums et surchargé l'opérateur implicite afin que je puisse l'affecter à des variables enum (dans mon cas, je devais lier un objet à une
ComboBox
valeur).Vous pouvez utiliser la réflexion pour mettre en forme les valeurs d'énumération comme vous le souhaitez, dans mon cas, je récupère les
DisplayAttribute
valeurs d'énumération (le cas échéant).J'espère que cela t'aides.
ÉDITER:
Au cas où, j'utilise la fonction suivante pour obtenir les
enum
valeurs que j'utilise pourDataSource
leComboBox
la source
Une fois que vous avez la
GetDescription
méthode (elle doit être statique globale), vous pouvez l'utiliser via une méthode d'extension:la source
la source
Vous pouvez définir Enum comme
puis utilisez
HowNice.GetStringValue()
.la source