ErikForwerk.Localization.WPF 0.2.2

There is a newer version of this package available.
See the version list below for details.
dotnet add package ErikForwerk.Localization.WPF --version 0.2.2
                    
NuGet\Install-Package ErikForwerk.Localization.WPF -Version 0.2.2
                    
This command is intended to be used within the Package Manager Console in Visual Studio, as it uses the NuGet module's version of Install-Package.
<PackageReference Include="ErikForwerk.Localization.WPF" Version="0.2.2" />
                    
For projects that support PackageReference, copy this XML node into the project file to reference the package.
<PackageVersion Include="ErikForwerk.Localization.WPF" Version="0.2.2" />
                    
Directory.Packages.props
<PackageReference Include="ErikForwerk.Localization.WPF" />
                    
Project file
For projects that support Central Package Management (CPM), copy this XML node into the solution Directory.Packages.props file to version the package.
paket add ErikForwerk.Localization.WPF --version 0.2.2
                    
#r "nuget: ErikForwerk.Localization.WPF, 0.2.2"
                    
#r directive can be used in F# Interactive and Polyglot Notebooks. Copy this into the interactive tool or source code of the script to reference the package.
#:package ErikForwerk.Localization.WPF@0.2.2
                    
#:package directive can be used in C# file-based apps starting in .NET 10 preview 4. Copy this into a .cs file before any lines of code to reference the package.
#addin nuget:?package=ErikForwerk.Localization.WPF&version=0.2.2
                    
Install as a Cake Addin
#tool nuget:?package=ErikForwerk.Localization.WPF&version=0.2.2
                    
Install as a Cake Tool

WPF Localization Framework

A lightweight and easy-to-use localization framework for WPF/XAML applications that enables runtime language switching with minimal configuration.

Features

This framework aims to simplify internationalization (i18n) in WPF applications by providing:

  • Simple XAML Integration: Use the loc:Localization markup extension directly in XAML
  • Runtime Language Switching: Change languages on the fly without restarting your application
  • CSV-based Translations: Easy-to-manage translation files in CSV format
  • Dynamic Binding Support: Bind translation keys dynamically using data binding
  • Placeholder Support: Include dynamic content in translations using placeholders
  • Resource Embedding: Embed translation files as resources in your assembly
  • Support for any CultureInfo: Works with any culture supported by .NET
  • Automatic Culture Detection: Detects and uses appropriate cultures automatically
  • Missing Translation Detection: Clearly marks missing translations for easy identification

Installation

NuGet Package

dotnet add package ErikForwerk.Localization.WPF

Or via NuGet Package Manager:

Install-Package ErikForwerk.Localization.WPF

Usage

1. Create Translation Files

Create CSV files for each language you want to support. The format is simple: Key;Translation

The resource name/filename must contain a culture name (e.g. "en-US", "de-DE", etc). The preferred format is filename.de-DE.csv.

Languages/en-US.csv:

// English language translations (en-US)
OtherTextKey;Other Text
BindingLanguageKey;Binding Language Key
Button:ChangeText;Change Text
PartA;Part A
PartB;Part B

2. Initialize LocalizationController

In your ViewModel or code-behind, initialize the LocalizationController and load your translation files:

using System.Globalization;
using ErikForwerk.Localization.WPF.Models;

public class MainWindowViewModel : INotifyPropertyChanged
{
    private LocalizationController _localization = new(System.Windows.Application.Current.MainWindow);

    public MainWindowViewModel()
    {
        // Load translations from embedded resources
        _localization.AddTranslationsFromCsvResource("Languages/de-DE.csv");
        _localization.AddTranslationsFromCsvResource("Languages/en-US.csv");
        _localization.AddTranslationsFromCsvResource("Languages/ru-RU.csv");
        _localization.AddTranslationsFromCsvResource("Languages/ja-JP.csv");
    }

    public IEnumerable<CultureInfo> SupportedCultures
        => _localization.SupportedCultures;

    public CultureInfo SelectedCulture
    {
        get => _localization.CurrentCulture;
        set
        {
            if (value == _localization.CurrentCulture)
                return;
            
            _localization.CurrentCulture = value;
            RaisePropertyChanged();
        }
    }
}

3. Use in XAML

Add the XML namespace to your XAML file:

xmlns:loc="clr-namespace:ErikForwerk.Localization.WPF;assembly=ErikForwerk.Localization.WPF"

The language of the window will be set when initializing the LocalizationController instance and when changing the CurrentCulture``on that instance using the Window` reference, that was handed in the constructor.

Static Translation

Use a static translation key directly:

<TextBlock Text="{loc:Localization StaticTextKey}" />
Dynamic Translation with Binding

Bind the translation key dynamically:

<TextBlock Text="{loc:Localization {Binding DynamicLangKey}}" />

In your ViewModel:

private string _dynamicLangKey = "BindingLanguageKey";

public string DynamicLangKey
{
    get => _dynamicLangKey;
    set
    {
        if (value == _dynamicLangKey)
            return;
        
        _dynamicLangKey = value;
        RaisePropertyChanged();
    }
}
Translation with Placeholders

Use the placeholders synthax in your translations to replacedifferent parts at runtime:

<TextBlock Text="{loc:Localization 'Foobar: %PartA% + %PartB%', ParsePlaceholders=True}" />

You can have non-translated text in combination with the placeholders, but only language-keys within %..% will be replaced. In the above example, the placeholders (PartA, PartB) will be replaced with their corresponding translations from the CSV file. You can also use binding in combination with placeholders.
To use % as part of the language key withing the placeholder-syntax, you need the escape the % using \% in the placeholder, for example %Value\%Offset%.

Language Selector

Create a ComboBox to let users switch languages. The SupportedCultures and SelectedCulture properties should be exposed in your ViewModel using the LocalizationController instance (see step 2 above):

<ComboBox
    DisplayMemberPath	="DisplayName"
    ItemsSource			="{Binding SupportedCultures}"
    SelectedItem		="{Binding SelectedCulture}" />

The bindings connect to properties in your ViewModel that wrap the LocalizationController.SupportedCultures and LocalizationController.CurrentCulture properties. See the Example Project for a complete implementation.

4. Handling Missing Translations

If a translation key is not found, the framework will display the key surrounded by exclamation marks, making it easy to identify missing translations:

<TextBlock Text="{loc:Localization MissingLangKey}" />

Example Project

For a complete working example, check out the WpfLocalizationExample project included in this repository. It demonstrates:

  • Setting up the LocalizationController
  • Static and dynamic translations
  • Placeholder replacement
  • Runtime language switching with a ComboBox
  • Multiple language support (English, German, Russian, Japanese)

Requirements

  • .NET 9.0 or higher
  • WPF Application

License

This project is licensed under the MIT License - see the LICENSE file for details.

Contributing

Contributions are welcome! Please feel free to submit a Pull Request.

Product Compatible and additional computed target framework versions.
.NET net9.0-windows7.0 is compatible.  net10.0-windows was computed. 
Compatible target framework(s)
Included target framework(s) (in package)
Learn more about Target Frameworks and .NET Standard.
  • net9.0-windows7.0

    • No dependencies.

NuGet packages

This package is not used by any NuGet packages.

GitHub repositories

This package is not used by any popular GitHub repositories.

Version Downloads Last Updated
0.9.0 96 3/29/2026
0.8.2 104 3/28/2026
0.7.1 112 1/4/2026
0.7.0 177 1/3/2026
0.6.0 382 11/16/2025
0.5.1 313 11/12/2025
0.5.0 317 11/11/2025
0.4.0 301 11/10/2025
0.3.0 244 11/1/2025 0.3.0 is deprecated because it is no longer maintained and has critical bugs.
0.2.2 230 10/30/2025
0.2.1 210 10/30/2025
0.2.0 230 10/30/2025
0.1.6 206 10/29/2025
0.1.4 207 10/29/2025