Sunday, September 19, 2010

Localization and Globalization in WP7 Applications Using Resource Files

I’ve been watching the progress of Windows Phone 7 for a while now and recently started developing a few applications that I hope to release to the marketplace when it opens later this year. One of the apps I have been working on uses .NET Resource files to allow label and button text to be translated into other languages. While the idea is simple the implementation was a bit more complicated than what I was expecting, so I thought I would post some details here to help guide others.

First off, if you are not familiar with .NET Resource files, I suggest watching this video on Globalization and Localization from the Windows Phone 7 in 7 training series, which gives a great overview of what each of the terms mean. In my case I was most interested in localization using separate resource files for each language, which was not covered in the video but is covered in the MSDN Windows Phone documentation linked to at the end of the video. This documentation was very helpful for setting up the resource files and creating a LocalizedStrings class, but after that they only provided one method of setting up the data binding for XAML objects. They also did not elaborate on some of the other options you can use when setting up localization resource files.

After a few tries and a bit of Google-fu I was able to get things setup how I wanted by adding these additional steps:

  1. I created all the Resource files and the LocalizedStrings class in a Localization folder to keep things organized. It use to be that the .RESX files had to be in a special Resource folder in Visual Studio, but with 2010 they can be stored anywhere you want. If you have a large application you would probably want to have multiple folders with their own set of resource files (ex: one for each UI page or section of your application). In this case you would still have a single LocalizedStrings class, but inside that class there would be public properties for multiple resource files (ex: MainPageResources, SettingsPageResources, etc…) instead of just one Localizedresources property. 
  2. The above articles specifically reference the en-US and es-ES cultures, but .NET also supports using just en or es for culture-invariant language specification, which is usually better if all you need is localization without currency or date/time format conversions. You can in fact create a general fr file that includes French translations and use that same file to support both France (fr-FR) and Canada (fr-CA) cultural variants. See MSDN for more information about the Hierarchical Organization of Resource Files and see this list for all of the specific languages and cultures supported by Silverlight.
  3. The MSDN article shows you how to setup the files and create the LocalizedStrings class, but they then assume that you know how to use that class for data binding. Visual Studio 2010 and Silverlight handle data binding differently than Winforms, and it gets even more confusing since XAML also has it’s own definition of Resources that are different then the .NET resources we just created. Silverlight also uses the term Resource to refer to files that use the the Build Action of "Content”, as these files get wrapped up into the .XAP file similar to how files with Build Action of "Resource” get embedded into the .Dll assembly (ex: loading an image from content or resource files). I found that instead of using the Text="{Binding Path=resourceFile.resourceName, Source={StaticResource Localizedresources }}" XAML syntax it was easier to use the following steps:
    1. Open your primary XAML page (usually MainPage.xaml) in the Visual Studio designer
    2. Open the properties for the PhoneApplicationPage and set the DataContext to be Application.Resources –> LocalizedStrings. NOTE: if you already are using a DataContext object, then you should integrate the LocalizedStrings class into that object so that it has localization support.
    3. Once the Page’s DataContext has been set you can change the data binding for any control on the page by simply selecting the property (ex: text, checked, etc), selecting “Apply Data Binding…”, and setting the Path to Localizedresources.BtnText or whatever the name of the desired resource value is.
  4. If you want to change the text in the Application Bar you have to jump through a few hoop because it is not actually a Silverlight control and does not support data binding. Instead you have to create or update the Application Bar at runtime.
I hope this helps!


Habeeb said...
This comment has been removed by the author.
Habeeb said...

Thanks. In short, its as simple as adding the resource file with entries and then binding.

Blog.TheG2.Net - Your guide to life in the Internet age.