Click here to Skip to main content
65,938 articles
CodeProject is changing. Read more.
Articles
(untagged)

WPF : Binding to an enum with localization

0.00/5 (No votes)
2 May 2014 1  
This article shows how to add a Combobox binded to an enum in a WPF control or application, in a very simple, and reusable way.

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
{
    /// <summary>
    /// This converter will try to find a string value in the current WPF application 
    ///     resources with a key which depends on the enum identifier
    /// </summary>
    public class Enum2LocalizedStringConverter : IValueConverter
    {
        public object Convert(  object value, Type targetType, object parameter,
                                System.Globalization.CultureInfo culture)
        {
            if (value != null)
            {
                // Build a resource key based on the enum type and value
                string Key = value.GetType().ToString() + "_" + value.ToString() + "_Traduction";
                // Try to find the traduction in the current application resources
                string Traduction = Application.Current.TryFindResource(Key) as string;
                if (Traduction == null)
                    // Traduction could not be found in the current application resources
                    return "Enum2LocalizedStringConverter : " + Key + " could not be found !!";
                return Traduction;
            }
            // return empty string if value is null
            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">
    <!-- EditableType enum traductions -->
    <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.

License

This article has no explicit license attached to it but may contain usage terms in the article text or the download files themselves. If in doubt please contact the author via the discussion board below.

A list of licenses authors might use can be found here