As you may know, localization and globalization of user interfaces have been a topic I like to discuss. Being bilingual, I like to give the opportunity to applications to show their glory in several languages.
In my previous jobs, I have localized ASP.NET Web Forms and ASP.NET MVC forms, and also Windows Forms, but the other day someone asked me about WPF/XAML and MVVM. How to localize a XAML markup.
This is what this post is all about. Back in 2007, a coworker and I wrote a Localization Toolkit and published all the code Open Source at CodePlex, after writing an article about the new features in .NET 2.0 and Visual Studio 2005 that allowed you to generate resources files from the literal strings embedded on an ASP.NET web form.
Fast forward a few years to the end of 2007 and beginning of 2008, with the outcome of WPF, are resources files still in use?
Yup, they still are, and they are selected by the same mechanism that selects a given satellite assembly given the UI Thread Culture. The same mechanism that was available in the .NET world in 2005 for ASP.NET Web Forms.
Satellite assemblies are nothing but key/value pairs stored in a resource file that the ResourceManager type can search by Key.
Now, let’s say I generated resource file (.resx) for a given locale and region (fr-FR or fr-CA) and I want the resource file key bound to the XAML view after the UI Culture Thread is set to the OS locale and region, or after the user selects the locale and region he would like. Notice there are two settings to set with the locale and region: the UI Thread and the current thread. They are different.
CultureInfo ci = new CultureInfo("fr-CA");
Thread.CurrentThread.CurrentCulture = ci;
Thread.CurrentThread.CurrentUICulture = ci;
How are the literal values bound to the proper resources file holding the locale and regional translation?
Within the Window tag of your XAML window file, add the following line of code:
xmlns:properties="clr-namespace:YourAssemblyName.Properties"
For each control within our grid (Button, Labels and Window Title) do not set the Title or Content values to static text. Instead use the resources file value.
<Label Content="{x:Static properties:Resources.LabelFirstName}"…/>
<Button Content="{x:Static properties:Resources.ButtonSubmit}"…/>
There are also other projects at GitHub that have been added recently specifically for WPF: WPFSharp.Globalizer which offers a better option than the LocBalm tool to generate and maintain the resources files for translation.
LocBaml is the de-facto tool documented on MSDN for WPF resource generation, but there are other projects such as the one mentioned above and the NuGet package ResXManager that offers more features.
LocBalm will generate UiDs on your XAML markup that will link automatically to the regional resource after the Current UI Thread is set. LocBalm can also be used to generate the different resource files after the application is developed, using the option to parse the main assembly for XAML markup.
Parlez vous Français? Oui, mais mon interface ne parler pas.