Localizing a Windows Phone (7) application
I’ve been trying to clean up the What’s Shaking, NZ? for Windows Phone 7 codebase recently, as there was quite a bit of duplicated code and plenty of room for problems (read: shitty code). I’ll be migrating it to Windows Phone 8 soon, and want it as clean as possible before I start.
One part of the clean up was localization. Localization of your resources is important, as it allows you to easily distribute your application in multiple languages without having to modify your code. Too few developers do this, and having an application display its content in the language of the device is a great way to make your users feel appreciated. I’ve done localization in Java previously, but never in .NET. I did some Googling and found a few guides, it was pretty simple:
- Add an
AppResources.resxfile (for your default language, as specified in Assembly Info for the project)
- Add some strings with keys
- Reference the keys in code wherever the strings are needed
- Additional languages are just
xxis the region and
YYis the language. For example,
AppResources.de-DE.resx. You can see the full list here.
- Finally edit the
*.csprojfile to include your newly supported languages.
Pretty simple. However, the guide I was following didn’t detail how to handle the case where you had multiple projects. Oh dear. I couldn’t find anything online about supporting multiple projects - other than just having a new
AppResources.resx file per project, which I didn’t want.
As it turns out, it’s still very simple to do. Instead of adding the
AppResources.resx file to the current project, just add a new project as a Windows Phone class library and then add the
AppResources.resx file to that. Now, you can reference it from anywhere, provided you include a reference and a
using statement from the other project back into the resources project:
1 2 3 4 5 6 7 8
To access the resources from XAML, you need to add the following class to your resources library:
1 2 3 4 5 6 7 8 9 10
You will also need to add the following to the
App.xaml file (the guide I linked to above doesn’t detail all of this):
1 2 3 4 5 6 7 8 9 10
And then to reference the resources in the XAML for each page, change anything that was using hardcoded text to use a binding as follows:
1 2 3 4
You can see all of these changes in this commit.
There are a few important gotchas with this:
- The DLL filename cannot end in “Resources”. I had some trouble with this, but I eventually found this blog post detailing the fact there are some reserved file names in XAP files. Specifically, you can’t have DLLs ending in ‘Resources’. If you have named your project as “Resources”, everything will compile fine but your app will crash when it runs. It’s easy enough to fix - I renamed my project (and the properties that named the DLL) from
WhatsShakingNZ.Localization. After doing this, everything worked perfectly.
- You must specify the
AppResources.resxAccess Modifier as
publicor you won’t be able to access the resource properties:
- The default language as specified in the Assembly Information under the project Properties window is the one that your default
AppResources.resxfile is considered to be. If the device your application is running on is running any language other than your default, it will search for the resource string in the corresponding language resource file. If that resource file does not exist (or, if the specific key it is looking for does not exist in that region-specific file), then it will fall back to your default. This means you can have some strings localised and some not, even within the same page.
- To support additional languages, you have to add the
AppResources.xx-YY.resxfile, and also declare in the
.csprojfile for the main project that it supports the language (not the project containing your resource files). You have to edit this file manually in a text editor, as detailed in step 4 of the guide linked above. You can check out this MSDN blog, this guide or this forum post for a bit more information on how and why.