Windows 8 Application Resource & Localization

To be successful mobile app for global market, localization of the app is very important aspect. In Silverlight and WPF, you would achieve the same using CultureInfo and resx files to separate out string resources of different cultures. Though in Windows 8 apps, resource localization is not as powerful as WPF but it relatively provides good support for building global aware apps. In this article, we will go through different techniques of localization of string and image resources.

Resw files
Windows 8 uses resw files to store localized strings. This file is nothing but an xml file stores key value pair. Unlike earlier resx file, there won’t be any strongly typed class generation. This file is then compiled to binary pri files. Programmatically, one can load this file using ResourceManager or ResourceLoader but you can take advantage of loading it automatically by arranging the resw file in proper folder structure as shown in Figure 1.0.


Figure 1.0 Folder structure for resw files

As per Figure 1.0, runtime will load the files automatically if the file is named Resources.resw and placed in a folder named with National Language Tag. The folder follows naming convention of having culture identifier (en, fr) and the country qualifier (US, fr). This helps runtime determine the right resource to load depends on a user Language Preference list. Now question may come to your mind that what is Language Preference list? Well, in .NET applications, CurrentCulture is the only way that enables determine the resource to load; either culture specific resource or the fallback resource. Windows 8 has introduced Language preferences which enables adding multiple languages. This way, runtime will try to load resources for preferred language and if preferred language is not found, runtime will load fallback language. To get the language preference for the current user, use
Windows.System.UserProfile.GlobalizationPreferences.Languages property.  Let’s start doing it!

Loading strings - XAML
Let’s create Windows 8.1 Empty Application project and add create folder structure as shown in Figure 1.0 and also add new item of type resw in each folder with default name. Once done, follow these steps.

1. Put one TextBlock in MainPage.xaml and set Uid as shown in Listing 1.0.

<TextBlock x:Uid="TitleText" />
Listing 1.0 Setting Uid for localization

2. Now add entry in en-US and fr-Fr folder’s resw file as shown in Figure 1.1 below.


Figure 1.1 Adding entry in resw file for en-US and fr-FR

Now you see that as per Figure 1.1, the resource entry in resw file follows naming convention like [Uid].[PropertyName].
Go ahead and run the app. You will see “how are you?” message in top left corner of the window. So far plain and simple. Now let’s play with Language Preference and set fr-FR as preferred language. Just put following line of code in MainPage’s constructor and run the app again.

Windows.Globalization.ApplicationLanguages.PrimaryLanguageOverride = "fr-FR";
Listing 1.1 Preferred language override to fr-FR

Now if you run the app and see, you will be presented with French version of the “how are you?” message.

Loading strings – Programmatically
Retrieveing a string in C# code is two steps process only using ResourceLoader class as shown in Listing 1.2 below.

            var resLoader = new ResourceLoader();
            var result = resLoader.GetString("TitleText/Text");

Listing 1.2 Retrieving resource using ResourceLoader

Note that there is syntax difference when retrieving the resource using ResourceLoader as you have to use [Uid]/[PropertyName]. There is more powerful approach to this using ResourceManager class which provides more robust API to deal with resources. Note that it requires good knowledge of binary compiled PRI files to work with. So code to read TitleText.Text would be something like Listing 1.3 below when you use ResourceManager.

            var resManager = Windows.ApplicationModel.Resources.Core.ResourceManager.Current;
            var subtree = resManager.MainResourceMap.GetSubtree("Resources");
            var value = subtree.GetValue("TitleText/Text").ValueAsString;

Listing 1.3 Retrieving resource using ResourceManager

So this was all about string resource localization. What if you want to localize images? Well in that case you can simply have localized version of each image in say Assets folder in their respective culture folder following same naming conventions such as en-US, fr-FR folder. Once that is in place, you can simply have Uid set for Image control and Source property is set in resw file for every culture.

CustomResource MarkupExtension
If you have ever developed custom markup extension in WPF/Silverlight, this approach is very similar to that.
First thing is to develop translation provider which inherits from CustomXamlResourceLoader class as Listing 1.4.

using Windows.ApplicationModel.Resources;
using Windows.UI.Xaml.Resources;

namespace LocalizationSample
{
    public class CustomResourceLoader : CustomXamlResourceLoader
    {
        readonly ResourceLoader _resourceLoader = new ResourceLoader();

        protected override object GetResource(string resourceId, string objectType, string propertyName, string propertyType)
        {
            return _resourceLoader.GetString(resourceId);
         }
    }
}

Listing 1.4 Custom resource loader

Now it’s time to register it. To do so, put code shown in Listing 1.5 in App.xml.cs’s constructor.
         
public App()
        {
             this.InitializeComponent();
             Windows.UI.Xaml.Resources.CustomXamlResourceLoader.Current = new CustomResourceLoader();

         }

Listing 1.5 Registering custom resource loader

Once we are done with registering the custom loader, you can simply use it like following:

<TextBlock Text="{CustomResource TitleText/Text}" />

Listing 1.6 Registering custom resource loader

That's all with localization of Windows 8 apps. You can grab the source code here.

By jay nanavati   Popularity  (4416 Views)