When I design a new application I always design it with localization in mind. For cross platform applications my strategy is based on the use of resource files in a Portable Class Library (PCL) project. See my previous article on Internationalization of a Cross Platform Application for details on details about how to do localization in a cross platform application.
For localization I use the Multilingual App Toolkit (MAT). MAT was created to easy the task of localizing Windows Store and Windows Phone applications and since version 3.0 it could also be used in desktop applications (Asp.Net MVC, WinForms and WPF). But what about PCLs? Can MAT be used in PCLs? Well, if you’re using version 3.1 then yes, you can use MAT in PCLs. If you’re using version 3.0 or lower then yes, you can enable a PCL project for translation with MAT, and no, it doesn’t work as it is supposed to. Let’s show how to have MAT work in a PCL project and how to solve the compilation problem you get if your project was enabled with MAT 3.0.
Create a PCL project and enable MAT on it
(note: I’m using Visual Studio 2013 Update 2 and Multilingual App Toolkit 3.1)
Start Visual Studio and create a new “Class Library (Portable)” project and call it “Portable” (or whatever you want).
In the target frameworks dialog, add the targets you need. I will add the newest ones: “Windows Phone 8.1”, “Windows 8.1” and “.Net Framework 4.5”.
The combination of target frameworks you choose will determine the kind of resources files you can add to the PCL project. There are basically two types of resource files:
- .resx: This type of resource has a strong type associated to it which allows to use strings in code. It is used by Windows Phone Silverlight 8/8.1 and .Net Framework 4.5 targets.
- .resw: This type does not have a strong type associated (although you can create one by using ResW File Code Generator). It is used by Windows 8/8.1 and by Windows Phone 8.1 targets.
When any of the selected targets uses .resx files then the PCL project will use .resx files. Otherwise the PCL project will use .resw files. In my case, since I chose “.Net Framework 4.5” as one of the targets my PCL project will use .resx resources. Having a strong type associated with my resource is very important later when using resources in the UI and app logic. (See my article on How to use Multilingual App Toolkit in Universal Apps for more information)
Now, delete the file Class1.cs generated by the Visual Studio wizard. The first thing you will be tempted to do is to enable MAT on the project. Select the project (not the solution) in Solution Explorer and from the Tools menu select “Enable Multilingual App Toolkit”. You will get the following message:
The message is pretty clear: we need to add a resource file before we can enable MAT. Let’s put our resource files in a folder called Resources. Right click on the project in Solution Explorer and from the popup menu select “Add” and then “New Folder” and call it Resources. New let’s add a resource file, right click on the newly created folder and from the popup menu select “Add” and then “New Item…”. The Visual Studio “Add New Item” dialog appears:
Select “Resource File” from the list of templates and name it Resources.resx. Add some strings to your resource file and make sure to that the “Access Modifier” for the resource is marked “Public” (cause we want to access to the strong type generated from other projects):
Compile your project. Now we are ready to enable MAT on the project. Select the project (not the solution) in Solution Explorer and from the Tools menu select “Enable Multilingual App Toolkit”. When MAT is enabled by default the Pseudo Language file is added automatically to the project. You can remove this file (Resources.qps-ploc.xlf) if you want. Let’s add a new language.
Right click on the project in solution explorer and from the popup menu select “Add translation languages…”. MAT will open the “Translation Languages” dialog where you can select the languages your app will support. In my case I will add Spanish (es) and Italian (it). Click OK to close the dialog. MAT will add .xlf files to your project for each of the languages you chose. Your solution now should look something like this:
Now, compile the project.
Solving the compilation error if using Multilingual App Toolkit prior to 3.1
If you’re not using the latest version of MAT (at the time of this writing is 3.1) then you will probably get the following error:
If you enabled MAT and added languages to your project with a version of MAT prior to 3.1 then you will probably get the error above. If you installed MAT 3.1 new projects will be created fine, but old projects will still present the error. To fix this you will need to edit your project file. If you take a closer look to the build output you will find the following message: “No XLIFF language files were found. The app will not contain any localized resources.” This means that MAT is not able to find the files with extension .xlf in the project. Right click on the project in Solution Explorer and from the popup menu choose “Unload Project”, and then again right click on the (now unloaded) project and select “Edit Portable.cproj”. Visual Studio will open the project file. Locate the following lines:
<None Include="Resources\Resources.es.xlf"> <Generator>XliffResxGenerator</Generator> <LastGenOutput>Resources.es.resx</LastGenOutput> </None> <None Include="Resources\Resources.it.xlf"> <Generator>XliffResxGenerator</Generator> <LastGenOutput>Resources.it.resx</LastGenOutput> </None>
And change the node name from None to XliffResource:
<XliffResource Include="Resources\Resources.es.xlf"> <Generator>XliffResxGenerator</Generator> <LastGenOutput>Resources.es.resx</LastGenOutput> </XliffResource> <XliffResource Include="Resources\Resources.it.xlf"> <Generator>XliffResxGenerator</Generator> <LastGenOutput>Resources.it.resx</LastGenOutput> </XliffResource>
Now, reload the project: right click on the project in Solution Explorer and from the popup menu select “Reload Project”. Now you should be able to compile the project.
Now I have my resource files in a PCL project, and since I’m using resx files I also have a public resources type that I can use in MVVM and databinding. See more details on how to do this in these two articles: