Don't! Enums are primitives and not UI objects - making them serve the UI in .ToString() would be quite bad from a design standpoint. You are trying to solve the wrong problem here: the real issue is that you do not want Enum.ToString() to show up in the combo box!

Now this is a very solveable problem indeed! You create a UI object to represent your combo box items:

I agree wholeheartedly. Neither should you expose the result of ToString() to the UI. And, you don't get localization.
–
Øyvind SkaarApr 28 '09 at 7:49

I know this is old, but how is that any different?
–
nportelliFeb 28 '13 at 14:54

2

I've seen a similar solution where instead of using a custom class, they mapped the enum values to a Dictionary and used the Key and Value properties as the DisplayMember and ValueMember.
–
Jeff BridgmanJul 12 '13 at 21:39

You're handling Enum -> String, but you will also need Enum > InstanceDescriptor, and String -> Enum if you want a complete implementation. But I guess displaying it is enough for your needs at the moment. ;)
–
Simon SvenssonApr 28 '09 at 9:14

This solution only works when your descriptions are static, unfortunately.
–
vansllyJul 1 '10 at 22:01

By the way, the use of TypeConverter is not bound to static descritions, coverter can populate values from other sources than attributes.
–
Dmitry TashkinovAug 25 '10 at 9:06

2

Been pulling my hair for a few hours now, but it still doesn't seem to work even in simple console apps. I decorated the enum with [TypeConverter(typeof(EnumToStringUsingDescription))] public enum MyEnum {[Description("Blah")] One}, tried doing Console.WriteLine(MyEnum.One) and it still comes out as "One". Do you need some special magic like TypeDescriptor.GetConverter(typeof(MyEnum)).ConvertToString(MyEnum.One) (which does work fine)?
–
DavJun 29 '11 at 15:31

@Dav - did you ever figure it out? I'm getting the same issue
–
drzausJan 10 '13 at 21:12

You could make a generic struct that you could use for all of your enums that has descriptions. With implicit conversions to and from the class, your variables still works like the enum except for the ToString method:

I don't think you can do it without simply binding to a different type - at least, not conveniently. Normally, even if you can't control ToString(), you can use a TypeConverter to do custom formatting - but IIRC the System.ComponentModel stuff doesn't respect this for enums.

You could bind to a string[] of the descriptions, or a something essentially like a key/value pair? (desription/value) - something like:

And seeing how the original poster explicitly did not want a class. I dont't think a class is that much more work. You can abstract the description and ToString override away to a parent class for all enums. After this all you need is a constructor private HowNice(String desc) : base(desc) { } and the static fields.
–
Mikko RantanenApr 28 '09 at 7:40

Nice idea. But how would I use this with a combobox? Once the user selects an items from the combobox, how do I know which of the items he selected? Search by the Description string? That makes my skin itch... (there might be a string "collision" between Description strings)
–
scraimerApr 28 '09 at 7:47

The selected item's Key will be the actual enum value. Also, don't collide the description strings - how will the user tell the difference?
–
Richard SzalayApr 28 '09 at 7:52

<cont> if you have description strings that collide, then you shouldn't be binding the values of the enum to a combobox directly anyway.
–
Richard SzalayApr 28 '09 at 7:53

hmmm... Well, could you give me example code on how you would add items to the combobox? All I can think of is "foreach (string s in descriptionsDict.Values) { this.combobox.Items.Add(s); }"
–
scraimerApr 28 '09 at 7:56

On top of this, you could add a static "factory method" to create a list of combobox items given an enum type (pretty much the same as the GetDescriptions method you have there). This would save you of having to implement one entity per each enum type, and also provide a nice/logical place for the "GetDescriptions" helper method (personally I would call it FromEnum(T obj) ...

Create a collection that contains what you need (like simple objects containing a Value property containing the HowNice enum value and a Description property containing GetDescription<HowNice>(Value) and databind the combo to that collection.

As you can see, this collection is easily customizable with lambda's to select a subset of your enumerator and/or implement a custom formatting to string instead of using the GetDescription<T>(x) function you mention.

Excellent, but I'm looking for something that requires even less work in the code.
–
scraimerApr 28 '09 at 7:48

Even if you can use the same generic collection for this kind of thing for all your enumerators? I wasn't suggesting custom writing such a collection for each enum, of course.
–
peSHIrApr 28 '09 at 8:20

What you need is to turn an enum into a ReadonlyCollection and bind the collection to the combobox (or any Key-Value Pair enabled control for that matter)

First off you need a class to contain the items of the list. Since all you need is the int/string pair I suggest using an interface and a base class combo so that you can implement the functionality in any object you want:

Here is the interface and a sample class that implements it.Notice that the class' Key is strongly typed to the Enum, and that the IValueDescritionItem proprties are implemented explicitely (so the class can have whatever properties and you can CHOOSE the ones that implement the Key/Value pair.

Remember that your collection is typed with MyItem so the combobox value should return an enum value if you bind to the appropriate proprtie.

I added the T this[Enum t] property to make the collection even more usefull than a simple combo consumable, for example textBox1.Text = enumcol[HowNice.ReallyNice].NicenessDescription;

You can of course chose to turn MyItem into a Key/Value class used only for this puprose effectively skipping MyItem in the type arguments of EnumToReadnlyCollection altogether, but then you'd be forced to go with int for the key (meaning getting combobox1.SelectedValue would return int and not the enum type). You work around that if you create a KeyValueItem class to replace MyItem and so on and so forth...

I would go the following way to localize enum, as it can display meaningful and localized values to user, not just description, through a dropdownlist text field in this example.

First, I create a simple method called OwToStringByCulture to get localized strings from a global resources file, in this example it is BiBongNet.resx in the App_GlobalResources folder. Inside this resource file, make sure you have all strings the same as the values of the enum (ReallyNice, SortOfNice, NotNice). In this method, I pass in the parameter: resourceClassName which is usually the name of the resource file.

Next, I create a static method to fill a dropdownlist with enum as its datasource, called OwFillDataWithEnum. This method can be used with any enum later.

Then in the page with a dropdownlist called DropDownList1, I set in the Page_Load the following just one simple line of code to fill the enum to the dropdownlist.

BiBongNet.OwFillDataWithEnum<HowNice>(DropDownList1, "BiBongNet");

That's it. I think with some simple methods like these, you can fill any list control with any enum, with not just as descriptive values but localized text to display. You can make all these methods as extension methods for better use.