This blog post was authored by Dan Zucker, a program manager on the Windows Phone team.
- Adam
Here are the quick steps you need to take to set up a Windows Phone OS 7.1 Visual Studio project to use the techniques and features described in the blog posts Tips for Localizing Windows Phone 8 XAML Apps - Part1 and Tips for localizing Windows Phone apps – Part 2 to localize apps. Note that throughout these steps, you must replace
- Follow the steps in the Standard Localizing Steps section described in Tips for Localizing Windows Phone 8 XAML Apps - Part1 to make your single-language app ready for localization.
- Update the
node in the App.xaml file with the following code, where is replaced with your project name: XAML- <Application.Resources>
- <local:LocalizedStrings xmlns:local="clr-namespace:
" x:Key="LocalizedStrings"/> - Application.Resources>
The LocalizedStrings Application Resource, along with the LocalizedStrings class added in the next step provides a globally accessible means for your app to access its project’s localized resources. Although there are simpler ways to achieve that goal, the method described here provides the benefits of strong typing, including resource visibility in IntelliSense and compilation validation during coding. - Add a new class file named LocalizedStrings.cs to the project. Replace the existing code with the following, where
is replaced with your project name: C#- using
.Resources; - namespace
- {
- ///
- /// Provides access to string resources.
- ///
- publicclassLocalizedStrings
- {
- privatestaticAppResources _localizedResources = newAppResources();
- publicAppResources LocalizedResources { get { return _localizedResources; } }
- }
- }
- using
- Search the entire project for localized string resources. Update the project namespace as needed by including the following code, where
is replaced with your project name: C#- using
.Resources;
- using
- Add a folder named Resources to the project.
- Add a new resources file named AppResources.resx file to the new Resources folder.
- Add the language initialization resource strings ResourceFlowDirection and ResourceLanguage to AppResources.resx, as described in Tips for Localizing Windows Phone 8 XAML Apps - Part1. Typically, the value of the resource strings should be set to meet the traditional flow direction and locale of the neutral language (the one that a viewer of your app will see if they have selected a phone language that is not supported by your app).
Name
Value
Comment
ResourceFlowDirection
LeftToRight
Controls the FlowDirection for all elements in the RootFrame. Set to the traditional direction of this resource file's language.
ResourceLanguage
en-US
Controls the Language and ensures that the font for all elements in the RootFrame aligns with the app's language. Set to the language code of this resource file's language.
- Change the access modifier of AppResources.resx to "Public" by using the Access Modifier drop-down list at the top of the resource editor.
- Save and rebuild the solution.
- Add the following references to App.xaml.cs, where
is replaced with your project name: C#- using
.Resources; - using System.Threading;
- using System.Globalization;
- using System.Diagnostics;
- using System.Windows.Markup;
- using
- Add the InitializeLanguage function and call to the constructor of the App.xaml.cs file. Include the following using statements to reference System.Threading and System.Globalization at the beginning of the file. Also, add the declaration for the appForceCulture global variable to enable the international testing feature described in Tips for localizing Windows Phone apps – Part 2. C#
- // . . .
- publicpartialclassApp : Application
- {
- // Global variable to set app locale at launch for International testing
- // An empty value causes the app to following users phone language culture
- publicstaticString appForceCulture = "qps-ploc";
- ///
- /// Provides easy access to the root frame of the phone app.
- ///
- ///
The root frame of the phone app. - publicstaticPhoneApplicationFrame RootFrame { get; privateset; }
- ///
- /// Constructor for the Application object.
- ///
- public App()
- {
- // Global handler for uncaught exceptions.
- UnhandledException += Application_UnhandledException;
- // Standard XAML initialization
- InitializeComponent();
- // Phone-specific initialization
- InitializePhoneApplication();
- // Language display initialization
- InitializeLanguage();
- // . . .
- Add the InitializeLanguage method to App.xaml.cs:C#
- // Initialize the app's font and flow direction as defined in its localized resource strings.
- //
- // To ensure that your apps font is aligned with its supported languages and that the
- // FlowDirection for each of those languages follows its traditional direction, ResourceLanguage
- // and ResourceFlowDirection should be initialized in each .resx file to match these values with that
- // file's culture. For example:
- //
- // AppResources.es-ES.resx
- // ResourceLanguage's value should be "es-ES"
- // ResourceFlowDirection's value should be "LeftToRight"
- //
- // AppResources.ar-SA.resx
- // ResourceLanguage's value should be "ar-SA"
- // ResourceFlowDirection's value should be "RightToLeft"
- //
- // For more info on localizing Windows Phone apps see http://go.microsoft.com/fwlink/?LinkId=262072.
- //
- privatevoid InitializeLanguage()
- {
- try
- {
- // Change locale to appForceCulture if it is not empty
- if (String.IsNullOrWhiteSpace(appForceCulture) == false)
- {
- // Force app globalization to follow appForceCulture
- Thread.CurrentThread.CurrentCulture = new CultureInfo(appForceCulture);
- // Force app UI culture to follow appForceCulture
- Thread.CurrentThread.CurrentUICulture = new CultureInfo(appForceCulture);
- }
- // Set the font to match the display language defined by the
- // ResourceLanguage resource string for each supported language.
- //
- // Fall back to the font of the neutral language if the display
- // language of the phone is not supported.
- //
- // If a compiler error occurs, ResourceLanguage is missing from
- // the resource file.
- RootFrame.Language = XmlLanguage.GetLanguage(AppResources.ResourceLanguage);
- // Set the FlowDirection of all elements under the root frame based
- // on the ResourceFlowDirection resource string for each
- // supported language.
- //
- // If a compiler error occurs, ResourceFlowDirection is missing from
- // the resource file.
- FlowDirection flow = (FlowDirection)Enum.Parse(typeof(FlowDirection), AppResources.ResourceFlowDirection,false);
- RootFrame.FlowDirection = flow;
- }
- catch
- {
- // If an exception is caught here it is most likely due to either
- // ResourceLangauge not being correctly set to a supported language
- // code or ResourceFlowDirection is set to a value other than LeftToRight
- // or RightToLeft.
- if (Debugger.IsAttached)
- {
- Debugger.Break();
- }
- throw;
- }
- }
As the comments in the code explain, the InitializeLanguage method initializes the app's font and flow direction as defined in the localized resource strings.
As described in the blog posts Tips for Localizing Windows Phone 8 XAML Apps - Part1 and Tips for localizing Windows Phone apps – Part 2, when you add a language to your app using the Windows Phone 8.0 SDK, a resource file for that locale is created. In that .resx file, the ResourceLanguage and ResourceFlowDirection values are initialized for the locale of the language you added. When the app is launched, InitializeLanguage() uses the values of ResourceLanguage and ResourceFlowDirection to initialize the xml:lang and FlowDirection of the app’s Rootframe.
Typically the culture used by InitializeLanguage() is the culture the system chooses to most closely match to the user’s phone language setting. The appForceCulture clause allows you to override this with the culture of your choice, so that you can deploy and review your app in the language of your choice without the time-consuming process of changing settings or restarting the device or emulator. If you use this convenient method, don’t forget to also test the app to be sure that everything works as expected when you modify the Phone Language setting and reboot.