Click here to Skip to main content
15,879,184 members
Articles / Desktop Programming / WPF

Localization Made Easy in WPF

Rate me:
Please Sign up or sign in to vote.
2.33/5 (2 votes)
17 Feb 2010CPOL3 min read 24.8K   331   7   3
Easy way to localize your WPF app declaratively

Introduction

This article discusses an easy way to localize your WPF application.

Background

In this article, I will talk about localization in WPF applications. XAML is a great tool for declaratively creating application interfaces and we shall use this declarative power to leverage globalization / localization capabilities of .NET. While designing this feature, the following considerations were paramount:

  1. Localizing applications must be declaratively done in XAML with no code behind
  2. XAML code must be easy to read and maintain
  3. Runtime culture change support must be in place so applications need not reboot for culture change to take place (Note: This may or may not be a feature you would want.)
  4. Solution must be efficient both in terms of memory and CPU time since operations are performed on UI thread
  5. Design time experience must not be altered, so developers can develop UI based on default language without worrying about how it is localized at runtime

References

I took inspiration / ideas from the following posts:

Step 1 – Create Localized Resource Files

The first step is to create resource files that hold localized resources. I created a WPF application and under Property folder, I open Resources.resx and enter a string with key “Hello” and value “Hello”. This is my English resource file. Also what is most important is to pick Access Modifier as Public for this resource file or else XAML will not be able to access it.

I also created another resource file called Resources.ru-RU.resx and added it to the Property folder. In this resource file, I added a string with key “Hello” and value “????????????” which obviously means hello in Russian. So depending on the culture, application should pick the right string. Also notice that in this resource file, Access Modifier is set to No code generation.

Step 2 – Create a Simple Window

Next we create a simple window with two radio buttons to give the user the ability to switch cultures between English and Russian and a text block that would display hello string from the correct resource dictionary.

To localize a control, we need to set an attached property on the control called Localization. This property is of type LocalizationInfo that has two properties to support localization:

  1. Property – This is the actual DependencyProperty that should display localized value on the UI. In our example, we use TextBlock.TextProperty for this purpose.
  2. ResourceKey – This is the resource key within the resource file. In our case, this is “Hello”.

Here is the XAML definition of the window:

XML
<Window x:Class="Localization.Window1" 
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" 
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="clr-namespace:Localization" 
xmlns:resources="clr-namespace:Localization.Properties" 
Title="Window1" Height="300" Width="300">
<StackPanel ButtonBase.Click="OnLanguageChanged"> 
   <RadioButton x:Name="EnglishButton" Content="English" IsChecked="True"/> 
   <RadioButton Content="Russian"/> 
   <TextBlock Text="{x:Static resources:Resources.Hello}"> 
      <local:LocalizationManager.Localization> 
         <local:LocalizationInfo 
             Property="{x:Static TextBlock.TextProperty}" 
             ResourceKey="Hello"/> 
      </local:LocalizationManager.Localization> 
   </TextBlock> 
</StackPanel> 
</Window>

Note in bold the LocalizationInfo property and also design time text support via static Resources.Hello field. Also the radio buttons are hooked via attached handler to OnLanguageChanged method:

C#
private void OnLanguageChanged(object sender, RoutedEventArgs e) 
{ 
    Thread.CurrentThread.CurrentUICulture = 
          new CultureInfo((bool)EnglishButton.IsChecked ? "en-US" : "ru-RU"); 
    LocalizationManager.UpdateResources(); 
} 

How Does It All Work?

The magic of keeping track of localizable UI elements and updating their content is done within LocalizationManager class. UpdateResources is the interesting method:

C#
/// <summary> 
/// Updates the resources after a culture change has occurred 
/// </summary> 
public static void UpdateResources() 
{ 
    List<WeakReference> deadReferences = new List<WeakReference>(); 

    foreach (WeakReference reference in Elements) 
    {             
      FrameworkElement element = reference.Target as FrameworkElement;
      if (element != null) 
      { 
          LocalizationInfo localizationInfo = GetLocalization(element); 
          if (localizationInfo != null) 
          { 
             element.SetValue(localizationInfo.Property, 
                   Resources.ResourceManager.GetString( 
                   localizationInfo.ResourceKey, 
                   Thread.CurrentThread.CurrentUICulture)); 
          } 
      } 
      else 
      { 
          deadReferences.Add(reference); 
      } 
    } 

    foreach (WeakReference reference in deadReferences) 
    { 
      Elements.Remove(reference); 
    } 
}  

It basically iterates over HashSet of localizable FrameworkElements and updates the content for DependencyProperty from localized resources. Note that we maintain a HashSet of weak references so UI elements can still be garbage collected without us holding references. As a cleanup phase, we detect the dead references and remove them from the HashSet. That’s it! Now you know how to localize your WPF applications with minimal code!

History

  • 17th February, 2010: Initial post 

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)


Written By
Software Developer (Senior) MixModes Inc. | Research In Motion
Canada Canada
Ashish worked for Microsoft for a number of years in Microsoft Visual Studio (Architect edition) and Windows Live division as a developer. Before that he was a developer consultant mainly involved in distributed service development / architecture. His main interests are distributed software architecture, patterns and practices and mobile device development.

Currently Ashish serves as a Technical Lead at RIM leading next generation BlackBerry media experience and also runs his own company MixModes Inc. specializing in .NET / WPF / Silverlight technologies. You can visit MixModes at http://mixmodes.com or follow it on Twitter @MixModes

In his free time he is an avid painter, hockey player and enjoys travelling. His blog is at: http://ashishkaila.serveblog.net

Comments and Discussions

 
QuestionToolTip are not localising Pin
Member 934328327-Jan-16 22:46
Member 934328327-Jan-16 22:46 
GeneralMy vote of 1 Pin
AugustoRuiz17-Feb-10 22:32
AugustoRuiz17-Feb-10 22:32 
GeneralRe: My vote of 1 Pin
Ashish Kaila17-Feb-10 22:40
Ashish Kaila17-Feb-10 22:40 

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Praise Praise    Rant Rant    Admin Admin   

Use Ctrl+Left/Right to switch messages, Ctrl+Up/Down to switch threads, Ctrl+Shift+Left/Right to switch pages.