Selecting a value from an enumeration of appropriate values is a common task. A
ComboBox is a well suited GUI element for that purpose. The
ComboBox shows textual representations of all available values.
How do we get "nice" texts? A simple solution is the use of friendly names for the values, as does e.g. System.Drawing.Color[^] . But there is a drawback: a name must not contain white space (e.g. "Dark Blue" was changed to "
A more advanced solution uses the Description attribute[^]. A converter, e.g. Description Enum TypeConverter[^], is used for the conversions from the value to the string and vice versa. Also a converter implementing WPF’s
IValueConverter interface is available: Using DescriptionAttribute for enumerations bound to a ComboBox[^] .
When it comes to localization, things become more complicated. Most examples on the web only show how to get localized strings into the
ComboBox, but omit the step from a user selection back to the enum value. Only Sacha Barber’s great article Binding and Using Friendly Enums in WPF[^] shows how to do a two-way binding.
I found his solution too verbose:
- every enum value has to be decorated with a "
LocalizableDescription" attribute, and there the enum’s name is repeated, and the name of the resource.
ObjectDataProvider has to be created whenever such an enum is used – the information gets split up between the definition of the enum in a cs file, the localized strings in the resx files, and the
ObjectDataProvider in a xaml file…
Translating the enum value to string (and vice versa)
The Enum Description Converter
This component asks a
ResourceManager to get the localized string for the resource’s name. To keep things easy, the function "
CreateResourceName" returns the enum value’s name – you could change that function if you want to include e.g. the
TypeName of the enum or also its namespace.
ResourceManager is available, or if it did not return a value, the converter falls back to the
Description attribute, and if that does not help, it returns the name of the value.
But how do we get that
ResourceManager into the converter? Well, there’s a trick:
I created a new
Attribute to connect an
enumeration to a
Resource. Just add the name of the resource when you set the attribute:
public enum SimpleNumbers
When the converter is instantiated with the
Type of the enumeration as a parameter, the
ResourceAttribute is retrieved by reflection. Then the
ResourceManager can be created. It is important to check here that the
ResourceManager is valid – a typo in the resource name will not cause an exception in the constructor, only later on when a value has to be retrieved. That can be achieved by invoking the
This class derives from
ComboBox and does all the translation magic with the enum description converter. When its
EnumTypeName property is set, it retrieves the
Type of the
enumeration, and creates its internal enum description converter. It sets its
ItemsSource to the list of translations returned from the converter. That is, internally this
ComboBox works with a
list of strings.
For binding a value, a new
DependencyProperty is added: the
SelectedEnumValue property. When a user selects a different value from the
ComboBox, an overridden
OnSelectionChanged method translates the description of the newly selected value to the
enum value and sets the value of the dependency property. The
PropertyChangedCallback method updates the text of the
ComboBox when the bound value changes for other reasons.
Now it is easy to use the EnumComboBox in xaml:
<Utilities:EnumComboBox Height="25" HorizontalAlignment="Left" Margin="27,57,0,0"
Name="comboNumber" VerticalAlignment="Top" Width="230"
The Sample Code
I was not very creative when I coded the
enumeration: it only lists numbers from 0 to 10. The
enumeration is stored in the
BusinessLogic.dll, and there are also the resource files with the translations, and a
ResourceAttribute and the
EnumComboBox along with its dependencies are in
The main sample references both projects. There is a simple main window for choosing a language. When you click on "Go", the
CurrentUICulture of the
CurrentThread are set. The next window is bound to the
TestViewModel which relies on the
TestClass. In the
ComboBox, you see the names of the numbers in the selected language. "Show enum name" shows the name of the selected value. The selected value can also be changed by code: click on "Change number to Num_1" to set the value to
And for our Indian friends: Yes, of course, this works also with Indian languages – see the Hindi example. And when you have to deal with right-to-left (e.g. Urdu), set the
FlowDirection of the corresponding
FrameworkElement, as shown with the Hebraic example.
SelectedValue properties are still available and could cause confusion. I tried to overwrite the
SelectedItem property, even with a "
new" keyword, but that did not work.