Following the session that Glenn (twitter) and I presented at Community Day 2012 as members of the Belgian Windows Phone User Group, we’re writing a couple of posts explaining the topics and showing some code.
In this post we’re handling the use of resources in your Windows 8 Metro application. As your Windows 8 application can be made available word-wide through the marketplace, there’s no discussion that you should localize the app to target this global market.
Before Windows 8, if you were doing XAML development (WPF, Silverlight or Windows Phone), you could use data binding techniques to do the mapping from the RESX-generated class to the XAML UI. By placing the resource reference at the application level (App.xaml) it wasn’t too hard to do your localization. But now with Windows 8, it got even a lot easier: the app already loads your resource files and there’s a new way of binding in XAML using the x:Uid
attribute.
<TextBlock x:Uid="SomeText" Margin="0,0,18,0" Style="{StaticResource BodyTextStyle}"/>
What this line of XAML code tells is: go look in the resources, now stored in a RESW file, and find me the key SomeText
. But that’s only part of the story! Resource keys can now be build up out of 2 parts like SomeText.Text
, but also SomeText.Width
or any other property available on your XAML control, including attached properties. By using the x:Uid
attribute on the control, all available properties starting with the key are merged from the resources into your UI.
Everything is quite straightforward if all your resources are in the same assembly as your XAML views, but things start to get more difficult if you offload your resources to a separate assembly as these resources aren’t automatically merged into your application’s resources. In the sample code attached below, there’s a solution with 2 projects, both containing part of the resource files for the languages English (en) and Dutch (nl).
The first solution to access the resources in the OffloadingResources.Resources assembly is to retrieve them through C# code and push them into the correct properties.
public static class LocalizedNamesLibrary
{
static ResourceLoader _resourceLoader = null;
public static string GetResourceValue(string resourceName)
{
if (_resourceLoader == null)
{
_resourceLoader = new ResourceLoader("OffloadingResources.Resources/Resources");
}
return _resourceLoader.GetString(resourceName);
}
}
All this code does is providing a simple static method that returns the value of a given key. It’s easy and it works, right? But what about the newly given powers to automatically bind all attached properties of a given element? For that we have to tell our app that it has to go fetch the Resources
of the OffloadingResources.Resources assembly and bind to the AppTitle
key, which translates to:
<TextBlock x:Uid="/OffloadingResources.Resources/Resources/AppTitle" .. />
Once you have this in place, it’s quite easy to localize your app into multiple languages. Next to that you can even leverage the fact that the whole resource system built into Windows 8 not only knows your language and culture, but also the scale and color contrast in which the app runs. This enables you to provide the correct font and image sizes, text and (localized) images to make your app ready for the global marketplace.
Extra note
Testing for multiple languages can be hard and different languages also do have impact on the size of your controls (e.g. buttons) or the way Unicode characters are shown. To help you test, Windows has a concept of pseudo-localization (and a lot of the Windows builds are done on pseudo). By default this is not enabled, so you’ll have to go dig in your Windows registry at HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\Nls\Locale. Down there add the following string values:
This will result in the following 3 locales for testing:
Base: qps-ploc
locale is used for English-like pseudo localizations. Its strings are longer versions of English strings, using non-Latin and accented characters instead of the normal script. Additionally simple Latin strings should sort in reverse order with this locale.
Mirrored: qpa-mirr
is used for right-to-left pseudo data, which is another area of interest for testing.
East Asian: qps-asia
is intended to utilize the large CJK character repertoire, which is also useful for testing.
Next up change your regional settings to one of these locales.
Don’t change the system locale itself or you’ll be greeted with a nice error during your next boot, resulting in a manual fix of the registry.
Example code: OffloadingResources.zip
Disclaimer: source code was written in Visual Studio 2012 RC