Introduction
I wrote this article because I tried to find a way to easily add a Combobox which is binded on enum typed data : SelectedValue is an enum typed property, and possible values are all the enum values. This is very simple and very oftently described in many articles / forum on the web, but there was no simple way to couple this with the possibility to localize enum values... And I found a very simple, and reusable solution to do this !
Using the code
The first part of the solution (binding a Combobox to an enum property by giving the user the possibility to chose between all the enum possible values) is very classic:
In XAML:
<Window.Resources>
<ObjectDataProvider MethodName="GetValues"
ObjectType="{x:Type sys:Enum}"
x:Key="MyEnumValues">
<ObjectDataProvider.MethodParameters>
<x:Type TypeName="local:MyEnum" />
</ObjectDataProvider.MethodParameters>
</ObjectDataProvider>
</Window.Resources>
<Grid>
<ComboBox HorizontalAlignment="Center" VerticalAlignment="Center"
ItemsSource="{Binding Source={StaticResource MyEnumValues}}"
SelectedValue="{Binding EnumProp, Mode=TwoWay}" />
</Grid>
and corresponding C# code:
public enum MyEnum
{
EnumVal1,
EnumVal2,
EnumVal3,
}
public partial class MainWindow : Window
{
public MainWindow()
{
DataContext = this;
InitializeComponent();
}
MyEnum _EnumProp = MyEnum.EnumVal2;
public MyEnum EnumProp
{
get { return _EnumProp; }
set { _EnumProp = value; }
}
}
With that code, you will obtain this Combobox :
The second part is the more interresing one (the one for which I did not succeed in finding any satisfying solution on any forum :-() will show a very simple and reusable solution pemitting to display a localized string for each enum value :
The idea is to use a generic converter to get localizable string values corresponding to enum values : this converter will try to find the string value in the current WPF application resources with a key which depends on the enum identifier :
using System;
using System.Windows;
using System.Windows.Data;
namespace LocalizedWPFComboBox
{
public class Enum2LocalizedStringConverter : IValueConverter
{
public object Convert( object value, Type targetType, object parameter,
System.Globalization.CultureInfo culture)
{
if (value != null)
{
string Key = value.GetType().ToString() + "_" + value.ToString() + "_Traduction";
string Traduction = Application.Current.TryFindResource(Key) as string;
if (Traduction == null)
return "Enum2LocalizedStringConverter : " + Key + " could not be found !!";
return Traduction;
}
return "";
}
public object ConvertBack( object value, Type targetType, object parameter,
System.Globalization.CultureInfo culture)
{
throw new NotImplementedException();
}
}
}
In the case of our example, this converter will try to find string resources with the keys LocalizedWPFComboBox.MyEnum_EnumVal1_Traduction for EnumVal1 value, LocalizedWPFComboBox.MyEnum_EnumVal2_Traduction for EnumVal2 value, etc... This XAML Dictionary can be used for example to traduce our enum values (excuse me but I'm french ;-) ) :
<ResourceDictionary xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:sys="clr-namespace:System;assembly=mscorlib">
-->
<sys:String x:Key="LocalizedWPFComboBox.MyEnum_EnumVal1_Traduction">Traduction française pour l'ID 'EnumVal1'</sys:String>
<sys:String x:Key="LocalizedWPFComboBox.MyEnum_EnumVal2_Traduction">EnumVal2 : merci qui ?</sys:String>
<sys:String x:Key="LocalizedWPFComboBox.MyEnum_EnumVal3_Traduction">EnumVal3 : merci Olivier ;-D</sys:String>
</ResourceDictionary>
With this converter and the associated string resources values, you just have to set the Combobox ItemTemplate with a TextBlock which uses the converter to display enum values :
<ComboBox HorizontalAlignment="Center" VerticalAlignment="Center"
ItemsSource="{Binding Source={StaticResource MyEnumValues}}"
SelectedValue="{Binding EnumProp, Mode=TwoWay}">
<ComboBox.ItemTemplate>
<DataTemplate>
<TextBlock Text="{Binding Converter={StaticResource Enum2LocalizedStringConverter}}" />
</DataTemplate>
</ComboBox.ItemTemplate>
</ComboBox>
With the final code described in this article, you will obtain this (localized) ComboBox :
Points of Interest
In my developments, I use this converter in a base library which is used in any projetcs : like this, configure the converter for any WPF Control binded to an enum, define the corresponding enum traduction in resources of the application, and it works !
History
2 May 2014 : creation of the article.