XAML binding resources from a separate assembly

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.

Windows 8 Resource file

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).

Windows 8 Resources example project structure

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:

Windows 8 pseudo locale keys

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.

Windows 8 pseudo locale region

Windows 8 pseudo locale region

Example code: OffloadingResources.zip
Disclaimer: source code was written in Visual Studio 2012 RC

Licensed under CC BY-NC-SA 4.0; code samples licensed under MIT.
comments powered by Disqus
Built with Hugo - Based on Theme Stack designed by Jimmy