By Poul Lorca · 10/2/2024

Easy Localization: A Simple Guide to Internationalizing Your WPF App

Tags: Desktop, Development

Tech: C#

Easy Localization: A Simple Guide to Internationalizing Your WPF App

Want to reach more users with your app? Making it available in multiple languages is a great way to expand your user base. In this easy-to-follow guide, we’ll walk you through the steps to add localization to your WPF application.

We’ll be using Avalonia UI and Rider in our examples, but the process is similar if you’re using Visual Studio or standard WPF. We’ll work within the MVVM (Model-View-ViewModel) pattern using data binding.

What We’ll Achieve

We’ll create a configuration that allows users to select the language of the application — for example, choosing between English, Spanish, and Portuguese. This selection will change elements like the text in the app’s menu, making your app accessible to a broader audience.

Creating the Translations

Step 1: Create a Resources Folder

First, create a folder named Resources in the root directory of your app. This folder will hold all the resource files for different languages.

Step 2: Create Resource Files for Each Language

Inside the Resources folder, create a resource file for each language you want to support:

Why Use .resx Files Instead of JSON or YAML?

A .resx file is an XML-based resource file used in .NET applications for storing strings and other resources. Here’s why we use .resx files:

While JSON or YAML could be used for storing strings, they lack the specialized support and features that .resx files offer for localization in .NET applications.

Step 3: Use Rider’s Localization Manager

Rider Localization Manager

If you’re using Rider, you can utilize the Localization Manager to work with your resource files easily:

  1. Open the Localization Manager in Rider.
  2. You’ll see the first column listing the resource keys (variable names).
  3. The following columns represent each language you’ve added.
  4. You can input the translated text for each key directly in the grid.

This tool makes it simple to keep your translations organized and consistent across different languages.

If You’re Not Using Rider

No worries if you’re not using Rider! You can create and manage .resx files manually. A .resx file is simply an XML file that contains key-value pairs, where each key is a variable name, and each value is the corresponding text in a specific language.

  1. Edit the Files Manually: Open each .resx file with a text editor or your IDE. The structure of a .resx file looks like this:
<?xml version="1.0" encoding="utf-8"?>
<root>
  <data name="MenuFile" xml:space="preserve">
    <value>File</value>
  </data>
  <data name="MenuEdit" xml:space="preserve">
    <value>Edit</value>
  </data>
</root>
  1. Add Your Translations: For each piece of text in your app that needs translation, add a element:

name Attribute: This is the key or variable name you’ll use in your code. Element: This contains the translated text for that key.

  1. Repeat for Each Language: Make sure that each .resx file has the same keys but with values translated into the respective language.
English Resource File Portuguese Resource File Spanish Resource File

By manually editing the .resx files, you’re doing exactly what tools like Rider’s Localization Manager do behind the scenes.

How to Use It in the App

Step 1: Create a Localization Service

We’ll create a service that loads the appropriate resource file based on the selected language.

LocalizationService.cs

using System.Globalization;
using System.Resources;

public class LocalizationService
{
    private ResourceManager _resourceManager;
    private CultureInfo _currentCulture;

    public LocalizationService()
    {
        _resourceManager = new ResourceManager("YourAppNamespace.Resources.Strings", typeof(LocalizationService).Assembly);
        _currentCulture = CultureInfo.CurrentCulture;
    }

    public string GetString(string key)
    {
        return _resourceManager.GetString(key, _currentCulture);
    }

    public void SetCulture(string cultureCode)
    {
        _currentCulture = new CultureInfo(cultureCode);
    }
}

Explanation:

Step 2: Modify the Main Window to Change Languages

We’ll add a command to the main window to change the application’s language.

MainWindowViewModel.cs

using System.Windows.Input;
using CommunityToolkit.Mvvm.Input;

public partial class MainWindowViewModel : ViewModelBase
{
    private readonly LocalizationService _localizationService;
    
    public MainWindowViewModel()
    {
        _localizationService = new LocalizationService();
        ChangeLanguage("en"); // Default Language
    }

    public string MenuDashboard => _localizationService.GetString("MenuDashboard");
    public string MenuProducts => _localizationService.GetString("MenuProducts");

    public ICommand ChangeLanguageCommand => new RelayCommand<string>(ChangeLanguage);

    private void ChangeLanguage(string languageCode)
    {
        _localizationService.ChangeLanguage(languageCode);
        OnPropertyChanged(nameof(MenuDashboard));
        OnPropertyChanged(nameof(MenuProducts));      
    }
}

Explanation:

Step 3: Bind the View to the ViewModel

In your XAML file, bind the UI elements to the ViewModel properties.

MainWindow.xaml

<Menu>
    <MenuItem Header="{Binding MenuDashboard}" />
    <MenuItem Header="{Binding MenuProducts}" />
    <MenuItem Header="Language">
        <MenuItem Header="English" Command="{Binding ChangeLanguageCommand}" CommandParameter="en" />
        <MenuItem Header="Español" Command="{Binding ChangeLanguageCommand}" CommandParameter="es" />
        <MenuItem Header="Português" Command="{Binding ChangeLanguageCommand}" CommandParameter="pt" />
    </MenuItem>
</Menu>

How It Works Together:

Changing the Language

Data Binding

Conclusions

Localization in Action

Congratulations! You’ve added localization to your WPF application. This straightforward solution allows you to support multiple languages, making your app accessible to a wider audience.

Of course, there’s room for improvement:

Take this guide as a starting point in the internationalization of your apps. Happy coding!

Share this post!