Enums have many useful applications and are often used in CoboBoxes to let the user select things. In the code behind the enum values are often defined using more or less cryptic text, because neither spaces, special characters, or leading numbers can be used in enum values (for good reasons!). Therefor it is necessary to change the text to something more understandable (language-localized in some cases).
One way to achieve this is to create the ComboBox items manually, but it’s much more comfortable to fill the ComboBox items directly with the enum values, because you can get/set the SelectedItem without converting it back and forth from/to the enum value.
You can’t override the .ToString() method of the Enum type, so we have to come up with another solution.
Just like any other control, the ComboBox uses a Template to create its items. We will replace the default template with one that uses a Comverter to populate the items.
The converter will be called “EnumNameConverter” and that’s its code:
As you can see the converter checks if the passed value is of type Enum, so if it’s ‘misused’ it will not throw an Exception. Then it calls an extension method ‘GetValueName’ that will care for converting the Enum to a string. (We could do this in the Converter as well, but if we do it in an extension method, you can use it independently of the Converter.)
That’s the code of the GetValueName extension method:
We have three options to convert the Enum value to a string:
- If the GetValueNameMethod was set to something (I’ll come back to that later)
- The System.ComponentModel.DataAnnotiations.Display Attribute (its Name property) can be used to describe an Enum’s value directly in the definition – the downside: it only allows for static values, thus no localization logic is available
- The inherited .ToString() method that would be used by the default template
If either of the methods returns a null/whitespace/empty string, we will fall back to the next one.
Now let’s talk about the GetValueNameMethod property. It’s a static property of the EnumExtensions class. You can set it to any method of type void(string) of your liking. And it just happens that if you implement resource localization like explained in the samples (keyword: x:Uid) you will have a GetString(string) method that returns the localized string from your resource file. To localize an Enum you need to add a new entry to your Resources.resw file:
Now we can localize any Enum value to a string using the Enum.Value.GetValueName() method.
For the ComboBox to use the Converter, we need to define the new ItemTemplate. That’s the code:
To use the template from an extension method, a few tricks have to be used. I won’t go into the details, but you can contact me if you want to know^
For the TCD.Controls package, I wrote another extension method (to the ComboBox type) that applies this template for you. Just call .UseEnumItemTemplate() on the ComboBox you want to use with Enums.
Bottom line:
- EnumExtensions.GetValueNameMethod
- set this to your LocalizedStrings.GetString(string) method
- Enum.Value.GetValueName
- returns localized string, DisplayAttribute.Name, or .ToString
- ComboBox.SetUpItems
- fill the ComboBox with enum values (take a look at the overrides/parameters!)
- ComboBox.UseEnumItemTemplate
- prepare the ComboBox for the Enum items
I’ve uploaded a code sample to the MSDN sample gallery as well: http://code.msdn.microsoft.com/Localizing-Enums-in-a-27932222