In my “A Better Way to Data Bind Enums in WPF” post, I showed how we could use a combination of a custom MarkupExtention and TypeConverter to more easily data bind an ItemsControl to an Enum and display a custom description for each Enum value.  The result looked something like this:

I have recently received a question related to that post on how to go about adding support for localizing those descriptions.  Well, it just so happens to be extremely easy.  We will be building on top of the previous Enum sample from the previous post.  Let’s see what it take to localize enum descriptions in WPF.

Adding Localization Support

The first thing we need to do in order to localize enum descriptions is to create a custom Attribute.  I called mine LocalizedDescriptionAttribute, and it looks like this:

public class LocalizedDescriptionAttribute : DescriptionAttribute
{
    ResourceManager _resourceManager;
    string _resourceKey;

    public LocalizedDescriptionAttribute(string resourceKey, Type resourceType)
    {
        _resourceManager = new ResourceManager(resourceType);
        _resourceKey = resourceKey;
    }

    public override string Description
    {
        get
        {
            string description = _resourceManager.GetString(_resourceKey);
            return string.IsNullOrWhiteSpace(description) ? string.Format(“[[{0}]]”, _resourceKey) : description;
        }
    }
}

This custom attribute derives from the already existing DescriptionAttribute.  This allows us to override the Description property to provide our own implementation.  We are expecting a resourceKey which will be the unique name defined in our Resources.resx file.  We also need to know which Resource object to use, since you can create any number of uniquely named resource files in your application.  We then rely on the built-in ResourceManager, given the correct resourceType, to get the correct value depending on the current culture information.

Go ahead and add a coupld of Resource.resx files to the project and target your desired cultures.

Resource files

EnumResources.resx (English)

English resources

EnumResources.ja-JP.resx (Japanese)

Japanese resources

Now that we have our resource files, we need to modify our Enum to include the LocalizedDescriptionAttribute.  I will only modify the last three values.

[TypeConverter(typeof(EnumDescriptionTypeConverter))]
public enum Status
{
    [Description(“This is horrible”)]
    Horrible,
    [Description(“This is bad”)]
    Bad,
    [Description(“This is so so”)]
    SoSo,
    [LocalizedDescription(“Good”, typeof(EnumResources))]
    Good,
    [LocalizedDescription(“Better”, typeof(EnumResources))]
    Better,
    [LocalizedDescription(“Best”, typeof(EnumResources))]
    Best
}

Go ahead and run the code.  You should notice no change in the values themselves, but you will notice the values are being retrieved from our EnumResources.resx file.

Enum english descriptions

Now, go ahead and go into the App.xaml.cs and override the OnStartup method, and change the current CultureInfo.

protected override void OnStartup(StartupEventArgs e)
{
    CultureInfo info = new CultureInfo(“ja-JP”);
    Thread.CurrentThread.CurrentCulture = info;
    Thread.CurrentThread.CurrentUICulture = info;
}

Now run the app again.

Japanese resource descriptions

Now we can visually see our LocalizedDescriptionAttribute at work.  That’s it!  That’s all it takes to localize enum descriptions in WPF.  Hopefully you will find this useful, and maybe even use this approach in your WPF applications.  Be sure to check out the source code, and start playing with it.  As always, feel free contact me on my blog, connect with me on Twitter (@brianlagunas), or leave a comment below for any questions or comments you may have.

Brian Lagunas

View all posts

4 comments

  • Very elegant.
    But how can I bind SelectedValue in my combobox ?
    I want to bind the values Good/Better/Best.

  • Thank you for the reply, but I cannot get it working. I bind the SelectedItem, but I need a converter to convert the value ‘good’ to the Enum value ‘good’.

    public object Convert(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
    {
    return (Status)Enum.Parse(typeof(Status), value.ToString());
    }
    public object ConvertBack(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
    {
    return value.ToString();
    }
    What am I missing ?

Follow Me

Follow me on Twitter, subscribe to my YouTube channel, and watch me stream live on Twitch.