Localizing Silverlight-based Applications

Microsoft Silverlight will reach end of support after October 2021. Learn more.

Localization is the customization of applications for a given culture or locale. Localization consists primarily of translating the user interface into the language of a particular culture or locale. Localizing an application involves creating a separate set of resources (such as strings and images) that are appropriate for the users of each targeted culture or locale and that can be retrieved dynamically depending on the culture and locale.

This topic contains the following sections:

  • Localization and Resource Files

  • Localizing Out-of-Browser Applications

  • Localization and String Size

  • Displaying Chinese, Japanese, and Korean Text

  • Deploying a Targeted Localized Application

  • Retrieving Specific Localized Resources

Localization and Resource Files

The .NET Framework for Silverlight uses a hub-and-spoke model to package and deploy resources. The hub is the main assembly that contains the nonlocalizable executable code and the resources for a single culture, which is called the neutral or default culture. The default culture is the fallback culture for the application. It represents a region-neutral language such as "en" if the default language is English or "fr" if the default language is French. The spokes connect to satellite assemblies, and each satellite assembly contains the resources for a single supported culture, but does not contain any code. At run time, a resource is loaded from the appropriate resource file, depending on the value of the application's current user interface (UI) culture, which is defined by the CultureInfo.CurrentUICulture property.

The Hierarchical Organization of Resources

To understand how resources are loaded, it is useful to think of them as organized in a hierarchical manner. A localized application can have resource files at three levels:

  • At the top of the hierarchy are the fallback resources for the default culture, for example, English ("en"). These are the only resources that do not have their own file; they are stored in the main assembly.

  • At the second level are the resources for any region-neutral cultures. A region-neutral culture is associated with a language but not a region. For example, French ("fr") is a region-neutral culture.

  • At the bottom of the hierarchy are the resources for any specific cultures. A specific culture is associated with a language and a region. For example, French Canadian ("fr-CA") is a specific culture.

When an application tries to load a localized resource, the Resource Manager does the following:

  1. It tries to load the resource that belongs to the user's specific culture. If there is no satellite assembly for the specific culture, or if the resource cannot be found in it, the search for the resource continues with step 2.

  2. If there is no satellite assembly for the specific culture or the resource cannot be found in it, or if resources for the cultures defined by operating-system fallback logic cannot be found, the Resource Manager tries to load the resource from the satellite assembly for the parent of the current UI culture (the region-neutral culture).

  3. If the operating system provides a list of preferred fallback languages, the Resource Manager iterates the list and tries to load the resource for each culture until it finds a match. If there is no match, or if the operating system does not support fallback logic, it continues to the next step.

  4. If that satellite assembly does not exist, or if the resource cannot be found in it, the Resource Manager loads the fallback resources from the assembly that is specified by the System.Resources.NeutralResourcesLanguageAttribute class.

  5. If no resources are found, resources for the invariant culture are used.

Important noteImportant Note:

It is best to generalize as much as possible when deciding whether to store resources in satellite assemblies for specific cultures or for a neutral-neutral culture. For example, when you localize an application for the French (France) culture ("fr-FR"), we recommend that you store all resources that are common to French cultures in the satellite assembly for the region-neutral culture. This enables users of other French-speaking cultures, such as the French (Canada) culture ("fr-CA"), to access localized resources instead of the resources for the default culture.

Including Resources in a Silverlight-based Application

Visual Studio and the .NET Framework common language runtime handle most of the details of compiling the resource files and loading the appropriate resource for the user's current culture, provided that the resource files have been named correctly and the project has been configured properly. For information about including localized resource files in your application, see How to: Add Resources to a Silverlight-based Application.

After you add the localized resource files to your application, you can use the ResourceManager class to retrieve string resources. The following example illustrates how to retrieve a string named Greeting. (The Visual Basic code relies on the My.Resources class, which wraps calls to ResourceManager methods.) When you use the ResourceManager class, you do not have to specify the resources that you want to retrieve, unless you want to retrieve localized resources other than the resources for the current UI culture. The runtime automatically tries to retrieve the correct resource based on the current thread's CultureInfo.CurrentUICulture property. If a culture-specific resource for the current culture cannot be found, the runtime uses the method described in The Hierarchical Organization of Resources to provide a resource.

Dim greeting As String = My.Resources.StringLibrary.Greeting
ResourceManager rm = null;
rm = new ResourceManager("SilverlightApplication.StringLibrary", Assembly.GetExecutingAssembly());

string greeting = rm.GetString("Greeting");

When the project is compiled, the resources for the default culture are included in the main assembly for the Silverlight-based application, which is included in the .xap file. In addition, the satellite assembly for each culture that is specified by the <SupportedCultures> property in the project file is included in the application's .xap file. Each satellite assembly is also listed in the <Deployment.Parts> section of the AppManifest.xml file.

In the application's .xap file, each satellite assembly is packaged in a subdirectory of the application directory. The individual satellite assemblies are all named applicationName.Resources.dll and are stored in a subdirectory whose name specifies the culture that is represented by the satellite assembly's resources. For example, resources for the German (Germany) culture ("de-DE") are stored in the de-DE subdirectory.

This approach creates a download that includes all the localizable resources of a Silverlight-based application. If an application has been localized for many cultures or the size of localized resources is significant, this method of deployment will increase the size of the application and lengthen its download time. Instead, you can create separate versions of a Silverlight-based application that target specific cultures.

Making XAML Localizable

To make your application localizable, you should also modify the strings that are defined in your application's XAML. For example, your application might include a Button control that is defined as follows:

<Button Content="Click Me!" />

Instead of providing a single static string, you can make the XAML localizable so that the text displayed by the Button control reflects the user's culture.

Making XAML localizable is similar to localizing code: You place all the localizable strings into a separate resource (.resx) file, and you use XAML code that extracts the strings from that file. To extract the strings, you use the {Binding} markup extension to bind a XAML property to the strongly typed wrapper that Visual Studio generates for resource files. For instructions, see How to: Make XAML Content Localizable.

You can also make XML content, rich text, non-string values, and non-dependency properties localizable. These and other scenarios are discussed in the topics listed in the See Also section at the end of this topic.

Localizing Out-of-Browser Applications

To support localized out-of-browser applications, you have to create a new .xap file for each localized culture or locale that your application supports. In Visual Studio, you can do this by creating new build configurations. For more information, see Deploying a Targeted Localized Application later in this topic.

NoteNote:

For more information about developing out-of-browser applications, see Out-of-Browser Support and How to: Configure an Application for Out-of-Browser Support.

You may also want to make the window title, shortcut name, and description of the out-of-browser application localizable. Ordinarily, an out-of-browser application retrieves its window settings from the application's OutOfBrowserSettings.xml configuration file. To localize the application's window settings, you create a unique OutOfBrowserSettings.xml file for each culture that you support. For example, if you localize your application for the French (France) culture, you would create an OutOfBrowserSettings.fr-FR.xml file. You can then modify the project settings to use the new settings file. For detailed instructions, see How to: Localize Information About an Out-of-Browser Application.

Back to top

Localization and String Size

A translated string may take more room on the screen than the original string. If you are developing your Silverlight-based application in English and localizing it, you should assume that strings in some languages are about 40% longer than in English. For this reason, it is recommended that you use automatic layout for elements that contain localized text. This involves the following:

  • Avoid the Canvas control, which uses hard-coded sizes and positions. Instead, use the Grid control, the StackPanel, or other panel elements that support automatic layout.

  • Avoid Glyphs. Instead, use the TextBlock or TextBox controls.

  • For long strings, set TextWrapping="Wrap" on TextBlock controls.

  • Do not set the Height and Width properties of your TextBlock control. Let the Silverlight runtime decide the size automatically. You may also set either the Height or the Width property and let Silverlight calculate the other property. If you do this, be sure to set TextWrapping="Wrap".

Back to top

Displaying Chinese, Japanese, and Korean Text

To properly display Chinese, Japanese, and Korean text, Silverlight needs to know which language it is displaying, because the same Unicode characters are displayed differently depending on language. Silverlight determines the language from the FrameworkElement.Language property or from the xml:lang attribute. If your XAML applies to only a single language, you can simply set the property at the top of the file, as shown in the following example, which sets the language to Japanese.

<UserControl Language="ja-JP" />

However, if you want your XAML to be localizable, you want to set the Language property to a localized value. To do this, create an entry such as Language in your resource file, and assign it a value that is the name of the localized language or culture. Change the XAML to use a {Binding} markup extension in the same way that you would localize any other property. For example:

<UserControl Language="{Binding Path=SilverlightApp.Language, 
             Source={StaticResource LocalizedStrings}}"

Back to top

Deploying a Targeted Localized Application

In most cases, you want users to download a Silverlight-based application that contains only the resources of their neutral and specific culture, instead of the resources in the complete set of localized satellite assemblies. You can use Visual Studio to create a localized Silverlight-based application that contains a designated subset of your application's satellite assemblies. For instructions, see How to: Create a Build that Targets a Specific Culture. You can then use ASP.NET to deploy the application based on the user's culture.

Determining the User's Culture

After you create a set of .xap files that contain the localized resources, you must ensure that the user can download the version of the Silverlight-based application that is appropriate for his or her culture. There are many ways to do this. For example, you can let the user select a language from a portal page, you can read the headers in the user request and redirect the user to the localized application, or you can dynamically modify the HTML page served to the user so that it embeds the localized version of the application.

The following example illustrates one possible implementation. When the user requests a portal page, the ASP.NET page's current culture and current UI culture is automatically set to match the language preference from the user's browser settings. If a localized version of the Silverlight-based application is available for that language, the user is redirected to it. If not, and a Silverlight-based application for the user's region-neutral culture is available, the user is redirected to that application. Otherwise, the user is redirected to the application for the default culture. The example requires that the ASP.NET page's Page tab include the UICulture="auto" attribute.

Imports System.Globalization
Imports System.Threading

Partial Class _Default
    Inherits System.Web.UI.Page

   Protected Sub Page_Load(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Load
      ' Create array of available languages.
      Dim availableCultures() As String = {"fr-FR", "en-US"}
      Dim availableNeutralCultures() As String = {"fr", "en"}
      Dim url As String = "TestPage.html"

      ' Get user's language preferences.
      Dim currentUi As CultureInfo = Thread.CurrentThread.CurrentUICulture
      ' Redirect if user language preference is available.
      For Each culture As String In availableCultures
         If culture = currentUi.Name Then Response.Redirect(culture + "/" + url)
      Next

      ' Get user's neutral culture.
      Dim neutralCulture As CultureInfo = currentUi.Parent
      ' Determine if neutral culture is supported.
      For Each culture As String In availableNeutralCultures
         If culture = neutralCulture.Name Then Response.Redirect(culture + "/" + url)
      Next

      ' Fall through to non-localized version of application.
      Response.Redirect(url)
   End Sub
End Class
using System;
using System.Globalization;
using System.Net;
using System.Threading;
using System.Web;
using System.Web.UI; 

public partial class _Default : System.Web.UI.Page
{
   protected void Page_Load(object sender, EventArgs e)
   {
      // Create array of available languages.
      string[] availableCultures = {"fr-FR", "en-US"};
      string[] availableNeutralCultures = { "fr", "en" };
      string url = "TestPage.html";

      // Get user's language preferences.
      CultureInfo currentUi = Thread.CurrentThread.CurrentUICulture; 

      // Redirect if user language preference is available.
      foreach (string culture in availableCultures)
      {
         if (culture == currentUi.Name)
            Response.Redirect(culture + "/" + url);
      }

      // Get user's neutral culture.
      CultureInfo neutralCulture = currentUi.Parent;
      // Determine if neutral culture is supported.
      foreach (string culture in availableNeutralCultures)
      {
         if (culture == neutralCulture.Name)
            Response.Redirect(culture + "/" + url);
      }

      // Fall through to non-localized version of application.
      Response.Redirect(url);
    }
}

Back to top

Retrieving Specific Localized Resources

In some cases, you may want to retrieve resources from a culture other than the user's current culture. You can do this in two ways:

  • You can set the current culture and current UI culture of a Silverlight-based application in the Object tag that is responsible for loading the application from an HTML page by adding parameters such as the following:

    <param name="uiculture" value="pt-BR" />
    <param name="culture" value="pt-BR" />
    

    In this case, the values of uiculture and culture are used to initialize the thread cultures of the Silverlight-based application to "pt-BR" if that culture is supported on the client. If the value of the culture or uiculture parameter is auto or if the parameter is absent, the current culture and current UI culture default to the values defined by the client operating system that is running the browser.

  • You can set the current culture and current UI culture programmatically, typically in the application's Application.Startup event handler, by assigning a CultureInfo object that represents the specified culture to the System.Threading.Thread.CurrentThread.CurrentUICulture property. The following example illustrates how to do this. It creates an array of culture names, selects one at random, and uses it to set the application's current UI culture.

    Private Sub Application_Startup(ByVal o As Object, ByVal e As StartupEventArgs) Handles Me.Startup
       ' Create an array of culture names.
       Dim cultureStrings() As String = {"en-US", "fr-FR", "ru-RU", "en-GB"}
       ' Get a random integer.
       Dim rnd As New Random()
       Dim index As Integer = rnd.Next(0, cultureStrings.Length)
       ' Set the current culture and the current UI culture.
       Thread.CurrentThread.CurrentCulture = New CultureInfo(cultureStrings(index))
       Thread.CurrentThread.CurrentUICulture = New CultureInfo(cultureStrings(index))
    
       Me.RootVisual = New Page()
    End Sub
    
    private void Application_Startup(object sender, StartupEventArgs e)
    {
       // Create an array of culture names.
       string[] cultureStrings = { "en-US", "fr-FR", "ru-RU", "en-GB", "fr-BE", "de-DE" };
       // Get a random integer.
       Random rnd = new Random();
       int index = rnd.Next(0, cultureStrings.Length);
       // Set the current UI culture.
       Thread.CurrentThread.CurrentCulture = new CultureInfo(cultureStrings[index]);
       Thread.CurrentThread.CurrentUICulture = new CultureInfo(cultureStrings[index]);
    
        // Load the main control
        this.RootVisual = new Page();
    }
    

You can also retrieve a culture-specific resource on a resource-by-resource basis. To do this, specify the culture whose resource is to be retrieved in the call to the resource retrieval method. For example, to retrieve a string for the Spanish (Spain) culture ("es-ES") when the application's current culture is English (United Kingdom) ("en-GB"), you would call the ResourceManager.GetString(String, CultureInfo) method instead of the ResourceManager.GetString(String) method. Similarly, to retrieve an image or some other binary resource, call the ResourceManager.GetObject(String, CultureInfo) method instead of the ResourceManager.GetObject(String) method.

Back to top