134 votes

Comment puis-je avoir un enum lié combobox avec chaîne personnalisée mise en forme des valeurs enum ?

Dans le post Enum ToString, une méthode est décrite à l'utilisation de 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 la syntaxe comme:

GetDescription<HowNice>(NotNice); // Returns "Not Nice At All"

Mais ce n'est pas vraiment m'aider quand je veux simplement remplir une zone de liste déroulante avec les valeurs de l'enum, puisque je ne peux pas la force de la zone de liste déroulante appel GetDescription.

Ce que je veux a les conditions suivantes:

  • La lecture de (HowNice)myComboBox.selectedItem sera de retour la valeur sélectionnée comme la valeur d'enum.
  • L'utilisateur doit voir l'écran convivial cordes, et pas seulement le nom de l'énumération des valeurs. Donc, au lieu de voir "NotNice", l'utilisateur, voir "Not Nice At All".
  • Heureusement, la solution nécessitera que très peu de modifications au code existant énumérations.

Évidemment, je pourrais mettre en œuvre une nouvelle classe pour chaque enum que j'ai créer, et de remplacer son ToString(), mais c'est beaucoup de travail pour chaque enum, et je préfère éviter.

Des idées?

Bon, je vais encore jeter un câlin comme un bounty :-)

85voto

Anton Gogolev Points 59794

a tout ce dont vous avez besoin : la propriété, vous devez affecter à , et événement, où vous devrez placer désiré formatage logique. Par conséquent,

45voto

Sander Points 9804

Ne pas! Les énumérations sont primitives et non des objets d'INTERFACE utilisateur - faire au service de l'INTERFACE utilisateur .ToString() serait très mauvais d'un point de vue design. Vous essayez de résoudre le mauvais problème ici: le vrai problème est que vous ne voulez pas Enum.ToString() pour afficher dans la liste déroulante!

Maintenant, c'est un très solveable problème en effet! Vous créez un objet d'INTERFACE utilisateur pour représenter votre zone de liste modifiable éléments:

sealed class NicenessComboBoxItem
{
    public string Description { get { return ...; } }
    public HowNice Value { get; private set; }

    public NicenessComboBoxItem(HowNice howNice) { Value = howNice; }
}

Et puis il suffit d'ajouter des instances de cette classe de votre zone de liste modifiable, des Objets de collection et de définir ces propriétés:

comboBox.ValueMember = "Value";
comboBox.DisplayMember = "Description";

42voto

Simon Svensson Points 11667

Vous pourriez écrire un TypeConverter qui lit les attributs spécifiés pour recherchez-les dans vos ressources. Ainsi, vous obtiendriez un support multi-langue pour les noms d’affichage sans trop de tracas.

Examinez les méthodes ConvertFrom/ConvertTo de TypeConverter, puis utiliser la réflexion pour lire les attributs sur vos champsd’enum.

42voto

scraimer Points 7000

TypeConverter. Je pense que c'est ce que je cherchais. Je te salue, Simon Svensson!

[TypeConverter(typeof(EnumToStringUsingDescription))]
Enum HowNice {
  [Description("Really Nice")]
  ReallyNice,
  [Description("Kinda Nice")]
  SortOfNice,
  [Description("Not Nice At All")]
  NotNice
}

Tout ce que je dois changer dans mon enum est d'ajouter cette ligne avant de leur déclaration.

[TypeConverter(typeof(EnumToStringUsingDescription))]

Une fois que j'ai faire, tout enum sera affichée à l'aide de l' DescriptionAttribute de ses champs.

Oh, et l' TypeConverter serait défini comme ceci:

public class EnumToStringUsingDescription : TypeConverter
{
    public override bool CanConvertFrom(ITypeDescriptorContext context, Type sourceType)
    {
        return (sourceType.Equals(typeof(Enum)));
    }

    public override bool CanConvertTo(ITypeDescriptorContext context, Type destinationType)
    {
        return (destinationType.Equals(typeof(String)));
    }

    public override object ConvertFrom(ITypeDescriptorContext context, System.Globalization.CultureInfo culture, object value)
    {
        return base.ConvertFrom(context, culture, value);
    }

    public override object ConvertTo(ITypeDescriptorContext context, System.Globalization.CultureInfo culture, object value, Type destinationType)
    {
        if (!destinationType.Equals(typeof(String)))
        {
            throw new ArgumentException("Can only convert to string.", "destinationType");
        }

        if (!value.GetType().BaseType.Equals(typeof(Enum)))
        {
            throw new ArgumentException("Can only convert an instance of enum.", "value");
        }

        string name = value.ToString();
        object[] attrs = 
            value.GetType().GetField(name).GetCustomAttributes(typeof(DescriptionAttribute), false);
        return (attrs.Length > 0) ? ((DescriptionAttribute)attrs[0]).Description : name;
    }
}

Cela m'aide avec mon ComboBox cas, mais, évidemment, n'est pas réellement remplacer l' ToString(). Je crois que je vais régler cela en attendant...

31voto

Tyler Durden Points 602

À l’aide de votre exemple de l’énumération :

Créer 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 crédit va à Richrd Carr pour la solution

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X