.NET WPF / BAML

WPF and BAML localization from the compiled build.

Lingobit reads the BAML inside your compiled WPF assemblies, shows a visual preview while you translate, and writes satellite assemblies for each language, on .NET Framework 4.8 and .NET 5–10.

Already translated? See how migration works

Your build EXE MyApp.exe Lingobit Localizer Harbor Supply 12 New Order Neue Bestellung Customer: Kunde: Quantity: Menge: Create Cancel Erstellen Abbrechen The window as it is in the build, translated in the preview You ship EXE MyApp.exe DEde\ FRfr\ JAja\ The same MyApp.exe; MyApp.resources.dll in each language folder Your build EXE MyApp.exe Translate in LingobitPreview Harbor Supply 12 New Order Neue Bestellung Customer: Kunde: Quantity: Menge: Create Cancel Erstellen Abbrechen You ship EXE MyApp.exe unchanged DEde\ FRfr\ JAja\
Input
Your compiled .exe and .dll files
Output
.resources.dll satellite assemblies in culture folders
.NET
Framework 4.8 and .NET 5–10, detected automatically
Preview
Compiled BAML from the built application
On this page

Tutorial

Localize a WPF application with Lingobit, step by step.

The steps follow the WPF Localization sample that comes with Localizer: two windows in English, a German translation, and a second version of the application. Use your own build in the same way.

Before XAML <Window Title="New Order"> <TextBlock Text="Customer:"/> msbuild /t:updateuid After XAML <Window x:Uid="Window_1" Title="New Order"> <TextBlock x:Uid="TextBlock_1" Text="Customer:"/> Keep the keys: translations are matched to them in every next version. Before <Window Title="New Order"> <TextBlock Text="Customer:"/> msbuild /t:updateuid After <Window x:Uid="Window_1" Title="New Order"> <TextBlock x:Uid="TextBlock_1" Text="Customer:"/> Keep the keys: translations are matched to them in every next version.
Width="90" Neue Bestellung Kunde: Erstellen Noch heute versenden The text is cut Width="Auto" Neue Bestellung Kunde: Noch heute versenden Erstellen The text fits Width="90" The text is cut Neue Bestellung Kunde: Erstellen Noch heute versenden Width="Auto" The text fits Neue Bestellung Kunde: Noch heute versenden Erstellen
Text in code C# Show("File saved."); Stays in English in every language Extractor Text in resources C# Show(Strings.FileSaved); RESX Strings.resx FileSavedFile saved. DE Datei gespeichert. Translated with the windows Text in code stays in English C# Show("File saved."); Extractor Text in resources C# Show(Strings.FileSaved); RESX Strings.resx FileSavedFile saved. DE Datei gespeichert. Translated with the windows
  1. Before XAML <Window Title="New Order"> <TextBlock Text="Customer:"/> msbuild /t:updateuid After XAML <Window x:Uid="Window_1" Title="New Order"> <TextBlock x:Uid="TextBlock_1" Text="Customer:"/> Keep the keys: translations are matched to them in every next version. Before <Window Title="New Order"> <TextBlock Text="Customer:"/> msbuild /t:updateuid After <Window x:Uid="Window_1" Title="New Order"> <TextBlock x:Uid="TextBlock_1" Text="Customer:"/> Keep the keys: translations are matched to them in every next version.
  2. Width="90" Neue Bestellung Kunde: Erstellen Noch heute versenden The text is cut Width="Auto" Neue Bestellung Kunde: Noch heute versenden Erstellen The text fits Width="90" The text is cut Neue Bestellung Kunde: Erstellen Noch heute versenden Width="Auto" The text fits Neue Bestellung Kunde: Noch heute versenden Erstellen
  3. Text in code C# Show("File saved."); Stays in English in every language Extractor Text in resources C# Show(Strings.FileSaved); RESX Strings.resx FileSavedFile saved. DE Datei gespeichert. Translated with the windows Text in code stays in English C# Show("File saved."); Extractor Text in resources C# Show(Strings.FileSaved); RESX Strings.resx FileSavedFile saved. DE Datei gespeichert. Translated with the windows

Your build DLL MyApp.dll Project DE FR JA DLL MyApp.dll WindowsBAML MainWindow ExportOptions Strings.NET resources ExportSummaryFormat FileSaved Detected .NET 8 · 64-bit DLL Your build DLL MyApp.dll Project DE FR JA DLL MyApp.dll WindowsBAML MainWindow ExportOptions Stringsresources ExportSummaryFormat FileSaved Detected .NET 8 · 64-bit DLL
Your .NET 5–10 build EXE MyApp.exe only starts the app DLL MyApp.dll windows, BAML, resources Add DLL Orders.dll more windows Add … On .NET Framework 4.8 the windows are in MyApp.exe: add it. Your .NET 5–10 build EXE MyApp.exe only starts the app DLL MyApp.dll Add windows, BAML, resources DLL Orders.dll Add more windows On .NET Framework 4.8 the windows are in MyApp.exe: add it.
  1. Your build DLL MyApp.dll Project DE FR JA DLL MyApp.dll WindowsBAML MainWindow ExportOptions Strings.NET resources ExportSummaryFormat FileSaved Detected .NET 8 · 64-bit DLL Your build DLL MyApp.dll Project DE FR JA DLL MyApp.dll WindowsBAML MainWindow ExportOptions Stringsresources ExportSummaryFormat FileSaved Detected .NET 8 · 64-bit DLL
  2. Your .NET 5–10 build EXE MyApp.exe only starts the app DLL MyApp.dll windows, BAML, resources Add DLL Orders.dll more windows Add … On .NET Framework 4.8 the windows are in MyApp.exe: add it. Your .NET 5–10 build EXE MyApp.exe only starts the app DLL MyApp.dll Add windows, BAML, resources DLL Orders.dll Add more windows On .NET Framework 4.8 the windows are in MyApp.exe: add it.

Project MyApp.dll MainWindow ExportOptions Resources Harbor Supply Quantity: 12 Create Cancel New Order Neue Bestellung Customer: Kunde: SourceGerman New Order Neue Bestellung Customer: Kunde: Project MyApp.dll MainWindow ExportOptions Harbor Supply Quantity: 12 Create Cancel New Order Neue Bestellung Customer: Kunde: SourceGerman New Order Neue Bestellung Customer: Kunde:
ProjectDEFRJAMyApp.dllWindowsMainWindowStrings PrepareTranslationTaskImportTranslationResults TranslatorDENew OrderNeue BestellungCustomer:Kunde:CreateErstellenSourceGermanNew OrderNeue BestellungCustomer:Kunde:Quantity:Menge:Validation on save Or their CAT toolXLIFF 1.2for the tool the translatoralready uses ProjectDEFRJAMyApp.dllWindowsMainWindowStrings PrepareTranslation Task TranslatorDENew OrderNeue BestellungCustomer:Kunde:CreateErstellenSourceGermanNew OrderNeue BestellungCustomer:Kunde:Quantity:Menge:Validation on save Or their CAT toolXLIFF 1.2for the tool the translatoralready uses ImportResults
Project Auto Translate Using Harbor Supply 12 New Order Neue Bestellung Customer: Kunde: Quantity: Menge: Ship today Noch heute versenden Create Cancel Erstellen Abbrechen DeepL… Google Translate… Azure Translator… Translation Memory… Terminology… Pseudo Translate… Project Auto Translate Using Harbor Supply 12 New Order Neue Bestellung Customer: Kunde: Quantity: Menge: Ship today Noch heute versenden Create Cancel Erstellen Abbrechen DeepL… Google Translate… Azure Translator… Translation Memory… Terminology… Pseudo Translate…
  1. Project MyApp.dll MainWindow ExportOptions Resources Harbor Supply Quantity: 12 Create Cancel New Order Neue Bestellung Customer: Kunde: SourceGerman New Order Neue Bestellung Customer: Kunde: Project MyApp.dll MainWindow ExportOptions Harbor Supply Quantity: 12 Create Cancel New Order Neue Bestellung Customer: Kunde: SourceGerman New Order Neue Bestellung Customer: Kunde:
  2. ProjectDEFRJAMyApp.dllWindowsMainWindowStrings PrepareTranslationTaskImportTranslationResults TranslatorDENew OrderNeue BestellungCustomer:Kunde:CreateErstellenSourceGermanNew OrderNeue BestellungCustomer:Kunde:Quantity:Menge:Validation on save Or their CAT toolXLIFF 1.2for the tool the translatoralready uses ProjectDEFRJAMyApp.dllWindowsMainWindowStrings PrepareTranslation Task TranslatorDENew OrderNeue BestellungCustomer:Kunde:CreateErstellenSourceGermanNew OrderNeue BestellungCustomer:Kunde:Quantity:Menge:Validation on save Or their CAT toolXLIFF 1.2for the tool the translatoralready uses ImportResults
  3. Project Auto Translate Using Harbor Supply 12 New Order Neue Bestellung Customer: Kunde: Quantity: Menge: Ship today Noch heute versenden Create Cancel Erstellen Abbrechen DeepL… Google Translate… Azure Translator… Translation Memory… Terminology… Pseudo Translate… Project Auto Translate Using Harbor Supply 12 New Order Neue Bestellung Customer: Kunde: Quantity: Menge: Ship today Noch heute versenden Create Cancel Erstellen Abbrechen DeepL… Google Translate… Azure Translator… Translation Memory… Terminology… Pseudo Translate…

Pseudo Translate German Simulation · +30% Chinese Simulation Harbor Supply 12 Saved at 10:42 Orders ÖrderßÖ ?????? Customer: Cüßtömer:Cü 阿昂俩拉基豪拉恶: Quantity: Qüäntity:Qü 阿昂阿拉拉哈拉哟: Ship today Ship tödäyShi 俩色哈勒 拉基俄阿哟 Create Cancel CreäteC CäncelC 阿恶拉阿拉拉 阿阿拉阿拉瑟 Too long Still in English Not displayed Pseudo Translate German Simulation · +30% Chinese Simulation Harbor Supply 12 Saved at 10:42 Orders ÖrderßÖ ?????? Customer: Cüßtömer:Cü 阿昂俩拉基豪拉恶: Quantity: Qüäntity:Qü 阿昂阿拉拉哈拉哟: Ship today Ship tödäyShi 俩色哈勒 拉基俄阿哟 Create Cancel CreäteC CäncelC 阿恶拉阿拉拉 阿阿拉阿拉瑟 Too long Still in English Not displayed
Output · Validation C# Format String: inconsistent arguments ExportSummaryFormat Fixed Resource ExportSummaryFormat Source Export {0} pages to {1}. Export %d pages to %s. Export <b>all</b> pages. Export %1 pages to %2. German {0} Seiten nach {2} exportieren. %d Seiten nach %d exportieren. <b>Alle</i> Seiten exportieren. %1 Seiten nach %3 exportieren. {0} Seiten nach {1} exportieren. %d Seiten nach %s exportieren. <b>Alle</b> Seiten exportieren. %1 Seiten nach %2 exportieren. Output · Validation C# Format String: inconsistent arguments ExportSummaryFormat Fixed ExportSummaryFormat Source Export {0} pages to {1}. Export %d pages to %s. Export <b>all</b> pages. Export %1 pages to %2. German {0} Seiten nach {2} exportieren. %d Seiten nach %d exportieren. <b>Alle</i> Seiten exportieren. %1 Seiten nach %3 exportieren. {0} Seiten nach {1} exportieren. %d Seiten nach %s exportieren. <b>Alle</b> Seiten exportieren. %1 Seiten nach %2 exportieren.
Preview Druckeinstellungen Papier: A4 Kopien: 2 Exportieren Seiteneinrichtung Einrichten Does not fit the column Fits SourceGerman Paper:Papier: Copies:Kopien: Page Setup Seiteneinrichtung Einrichten ExportExportieren Preview Druckeinstellungen Papier: A4 Kopien: 2 Exportieren Seiteneinrichtung Einrichten Does not fit the column Fits SourceGerman Copies:Kopien: Page Setup Seiteneinrichtung Einrichten ExportExportieren
  1. Pseudo Translate German Simulation · +30% Chinese Simulation Harbor Supply 12 Saved at 10:42 Orders ÖrderßÖ ?????? Customer: Cüßtömer:Cü 阿昂俩拉基豪拉恶: Quantity: Qüäntity:Qü 阿昂阿拉拉哈拉哟: Ship today Ship tödäyShi 俩色哈勒 拉基俄阿哟 Create Cancel CreäteC CäncelC 阿恶拉阿拉拉 阿阿拉阿拉瑟 Too long Still in English Not displayed Pseudo Translate German Simulation · +30% Chinese Simulation Harbor Supply 12 Saved at 10:42 Orders ÖrderßÖ ?????? Customer: Cüßtömer:Cü 阿昂俩拉基豪拉恶: Quantity: Qüäntity:Qü 阿昂阿拉拉哈拉哟: Ship today Ship tödäyShi 俩色哈勒 拉基俄阿哟 Create Cancel CreäteC CäncelC 阿恶拉阿拉拉 阿阿拉阿拉瑟 Too long Still in English Not displayed
  2. Output · Validation C# Format String: inconsistent arguments ExportSummaryFormat Fixed Resource ExportSummaryFormat Source Export {0} pages to {1}. Export %d pages to %s. Export <b>all</b> pages. Export %1 pages to %2. German {0} Seiten nach {2} exportieren. %d Seiten nach %d exportieren. <b>Alle</i> Seiten exportieren. %1 Seiten nach %3 exportieren. {0} Seiten nach {1} exportieren. %d Seiten nach %s exportieren. <b>Alle</b> Seiten exportieren. %1 Seiten nach %2 exportieren. Output · Validation C# Format String: inconsistent arguments ExportSummaryFormat Fixed ExportSummaryFormat Source Export {0} pages to {1}. Export %d pages to %s. Export <b>all</b> pages. Export %1 pages to %2. German {0} Seiten nach {2} exportieren. %d Seiten nach %d exportieren. <b>Alle</i> Seiten exportieren. %1 Seiten nach %3 exportieren. {0} Seiten nach {1} exportieren. %d Seiten nach %s exportieren. <b>Alle</b> Seiten exportieren. %1 Seiten nach %2 exportieren.
  3. Preview Druckeinstellungen Papier: A4 Kopien: 2 Exportieren Seiteneinrichtung Einrichten Does not fit the column Fits SourceGerman Paper:Papier: Copies:Kopien: Page Setup Seiteneinrichtung Einrichten ExportExportieren Preview Druckeinstellungen Papier: A4 Kopien: 2 Exportieren Seiteneinrichtung Einrichten Does not fit the column Fits SourceGerman Copies:Kopien: Page Setup Seiteneinrichtung Einrichten ExportExportieren

Project MyApp.dll MainWindow ExportOptions Resources DE FR JA Create Localized Files Run Localized Application Release folder EXE MyApp.exe DLL MyApp.dll unchanged DEde\MyApp.resources.dll FRfr\MyApp.resources.dll JAja\MyApp.resources.dll Neue Bestellung Kunde: Harbor Supply Erstellen Abbrechen Project MyApp.dll MainWindow ExportOptions Create Localized Files EXE MyApp.exe · .dll unchanged DEde\ FRfr\ JAja\ Run Localized Application Neue Bestellung Kunde: Harbor Supply Erstellen Abbrechen
Release folder EXEMyApp.exe DEde\ FRfr\ JAja\ WPF loads the folder of the chosen language Harbor Supply 12 Neue Bestellung DateiSprache Kunde:Menge: Erstellen Abbrechen Deutsch Français 日本語 Nouvelle commande FichierLangue Client :Quantité : Créer Annuler Release folder EXEMyApp.exe DEde\ FRfr\ JAja\ Harbor Supply 12 Neue Bestellung DateiSprache Kunde:Menge: Erstellen Abbrechen Deutsch Français 日本語 Nouvelle commande FichierLangue Client :Quantité : Créer Annuler
  1. Project MyApp.dll MainWindow ExportOptions Resources DE FR JA Create Localized Files Run Localized Application Release folder EXE MyApp.exe DLL MyApp.dll unchanged DEde\MyApp.resources.dll FRfr\MyApp.resources.dll JAja\MyApp.resources.dll Neue Bestellung Kunde: Harbor Supply Erstellen Abbrechen Project MyApp.dll MainWindow ExportOptions Create Localized Files EXE MyApp.exe · .dll unchanged DEde\ FRfr\ JAja\ Run Localized Application Neue Bestellung Kunde: Harbor Supply Erstellen Abbrechen
  2. Release folder EXEMyApp.exe DEde\ FRfr\ JAja\ WPF loads the folder of the chosen language Harbor Supply 12 Neue Bestellung DateiSprache Kunde:Menge: Erstellen Abbrechen Deutsch Français 日本語 Nouvelle commande FichierLangue Client :Quantité : Créer Annuler Release folder EXEMyApp.exe DEde\ FRfr\ JAja\ Harbor Supply 12 Neue Bestellung DateiSprache Kunde:Menge: Erstellen Abbrechen Deutsch Français 日本語 Nouvelle commande FichierLangue Client :Quantité : Créer Annuler

MyApp.dll 1.0 1.1 New Order Customer: Client: Harbor Supply Quantity: 12 Ship today Gift wrap Create Cancel Project Scan for Changes Neue Bestellung Kunde: Updated Harbor Supply Menge: 12 Noch heute versenden Removed Gift wrap New Erstellen Abbrechen Rows are matched by x:Uid: Client keeps the translation of Customer. MyApp.dll 1.0 1.1 New Order Customer: Client: Harbor Supply Quantity: 12 Ship today Gift wrap Create Cancel Project Scan for Changes Neue Bestellung Kunde: Updated Harbor Supply Menge: 12 Noch heute versenden Removed Gift wrap New Erstellen Abbrechen Rows are matched by x:Uid.
Translated earlier MyApp.exe de\ DE MyApp.resources.dll fr\ FR MyApp.resources.dll Project Not Translated Imported DE FR MyApp.exe Dialogs Menus String Table Import from Localized Files Translated with another tool or long ago? Add your build: Lingobit finds the localized files and offers to import them. Import Translations from Localized Files Germande\MyApp.resources.dll Frenchfr\MyApp.resources.dll OK Cancel OK Translated earlier MyApp.exe de\ DE MyApp.resources.dll fr\ FR MyApp.resources.dll Project Not Translated Imported DE FR MyApp.exe Dialogs Menus String Table Import from Localized Files Translated with another tool or long ago? Add your build: Lingobit offers the import. Import Translations from Localized Files Germande\MyApp.resources.dll Frenchfr\MyApp.resources.dll OK Cancel OK
  1. MyApp.dll 1.0 1.1 New Order Customer: Client: Harbor Supply Quantity: 12 Ship today Gift wrap Create Cancel Project Scan for Changes Neue Bestellung Kunde: Updated Harbor Supply Menge: 12 Noch heute versenden Removed Gift wrap New Erstellen Abbrechen Rows are matched by x:Uid: Client keeps the translation of Customer. MyApp.dll 1.0 1.1 New Order Customer: Client: Harbor Supply Quantity: 12 Ship today Gift wrap Create Cancel Project Scan for Changes Neue Bestellung Kunde: Updated Harbor Supply Menge: 12 Noch heute versenden Removed Gift wrap New Erstellen Abbrechen Rows are matched by x:Uid.
  2. Translated earlier MyApp.exe de\ DE MyApp.resources.dll fr\ FR MyApp.resources.dll Project Not Translated Imported DE FR MyApp.exe Dialogs Menus String Table Import from Localized Files Translated with another tool or long ago? Add your build: Lingobit finds the localized files and offers to import them. Import Translations from Localized Files Germande\MyApp.resources.dll Frenchfr\MyApp.resources.dll OK Cancel OK Translated earlier MyApp.exe de\ DE MyApp.resources.dll fr\ FR MyApp.resources.dll Project Not Translated Imported DE FR MyApp.exe Dialogs Menus String Table Import from Localized Files Translated with another tool or long ago? Add your build: Lingobit offers the import. Import Translations from Localized Files Germande\MyApp.resources.dll Frenchfr\MyApp.resources.dll OK Cancel OK

WPF compiles XAML into BAML; languages ship as satellite assemblies.

When you build a WPF application, every window and page written in XAML is compiled into BAML and stored inside the assembly. Lingobit works on that compiled BAML: it writes the same windows in each language into a satellite assembly, and your code stays where it is.

Your build Lingobit Localizer XAML <Window x:Uid="Win_1" Title="New Order"> <TextBlock x:Uid="Txt_1" Text="Customer:"/> build DLL MyApp.dll Code BAML Win_1New Order Txt_1Customer: DE de\ MyApp.resources.dll BAML Win_1Neue Bestellung Txt_1Kunde: The keys stay the same in every build, so translations carry over to the next version. XAML Your build <Window x:Uid="Win_1" Title="New Order"> <TextBlock x:Uid="Txt_1" Text="Customer:"/> build DLL MyApp.dll code + BAML Win_1New Order Txt_1Customer: Lingobit DE de\MyApp.resources.dll Win_1Neue Bestellung Txt_1Kunde: The keys stay the same in every build, so translations carry over.

At startup, WPF picks the language folder.

.NET uses the current UI culture, from Windows or set by your application, and loads the windows from the matching folder next to the application. You copy the folders with the release; nothing is rebuilt.

At startup UI culture de-DE from Windows or set by the app Release folder EXE MyApp.exe DE de\ loaded FR fr\ JA ja\ The window Neue Bestellung Kunde: Menge: Erstellen in German At startup UI culture de-DE Windows or app EXE MyApp.exe DEde\ FRfr\ JAja\ Neue Bestellung Kunde: Erstellen Menge:

BAML or RESX: choose by what your build ships.

Most WPF text is in XAML and is compiled into BAML. Text that your XAML takes from .resx files, through {x:Static} bindings, is compiled into the same assembly, and Lingobit translates it there together with the windows. Translate the .resx files themselves only when the translated files must go back into source control.

The compiled-build workflow and the RESX workflow for WPF
Compiled build RecommendedRESX files Alternative
Input.exe, .dll.resx files from your source
What gets translatedWindows (BAML) and the .NET resources in the same assembliesThe strings in the .resx files only
PreviewThe WPF windows, as they are in the buildNone: a list of strings
Output.resources.dll satellite assemblies, ready to shipTranslated .resx files; your build makes the satellites
Use whenYou ship the compiled application; this is most WPF projectsTranslated .resx files must stay in source control

.NET Resources guide for the RESX workflow

Reference

Culture decides which resources load and how text behaves.

If the application does not set a language itself, .NET uses the current UI culture and loads the best match it has: de-AT, then de, then the neutral resources in the main assembly.

WPF looks in order de-AT de-AT\ not shipped de de\ found neutral MyApp.exe English Neue Bestellung Kunde: Menge: Erstellen Abbrechen The window, from de\ WPF looks in order de-AT de-AT\ not shipped de de\ found neutral MyApp.exe English Neue Bestellung from de\ Kunde: Menge: Erstellen
  • Each window is looked up on its own. A window comes whole from one folder; a window that is missing in de\ opens in the neutral language.
  • Ship the parent culture. A de\ folder serves de-DE, de-AT, and de-CH; add de-CH\ only when Swiss German text differs.

Choose the language in your app instead of relying on fallback.

Many applications let users pick the language. Set the culture yourself, before WPF loads the first window:

  1. List the languages you ship from the culture folders next to the application.
  2. Read the saved choice or a command-line switch; fall back to the source language.
  3. Set CurrentUICulture before InitializeComponent of the application.
  4. Restart to switch after the user picks another language.
[STAThread]
public static void Main(string[] args)
{
    var culture = CultureInfo.GetCultureInfo(LoadSavedLanguage() ?? "en-US");
    CultureInfo.DefaultThreadCurrentCulture = culture;
    CultureInfo.DefaultThreadCurrentUICulture = culture;
    Thread.CurrentThread.CurrentCulture = culture;
    Thread.CurrentThread.CurrentUICulture = culture;

    var app = new App();
    app.InitializeComponent();
    app.Run();
}

The WPF sample does exactly this: its Language menu lists only the cultures whose satellites contain the windows, and --culture de-DE starts it in German.

xml:lang and neutral resources.

xml:lang

Set it in the WPF source when the application needs language-specific text behavior: font fallback, number substitution, spell checking, hyphenation, and text shaping. It is part of the application setup, not of the translation.

Neutral resources

Set UICulture only when the neutral-language BAML should go into a neutral-language satellite assembly; keep NeutralResourcesLanguage and UltimateResourceFallbackLocation aligned with that choice.

Show the settings

Neutral resources in the main assembly

[assembly: NeutralResourcesLanguage(
    "en-US",
    UltimateResourceFallbackLocation.MainAssembly)]

Neutral resources in a satellite assembly

<PropertyGroup>
  <UICulture>en-US</UICulture>
</PropertyGroup>

[assembly: NeutralResourcesLanguage(
    "en-US",
    UltimateResourceFallbackLocation.Satellite)]
<Window x:Class="MyApp.MainWindow" xml:lang="de-DE">

Do and don't.

Do

  • Localize the build you release, every time from the current files.
  • Keep x:Uid values stable between versions.
  • Pseudo-translate and run the build before translators start.
  • Look at long translations in the preview.
  • Ship the parent culture folder, such as de\.

Don't

  • Regenerate UIDs after localization has started.
  • Give windows fixed widths that only fit English.
  • Build UI text in code from pieces of strings.
  • Mix the two neutral-resource layouts in one project.
  • Set the culture after the first window is created.

Troubleshooting.

Symptoms, causes, and what to do
SymptomLikely causeWhat to do
The application stays in EnglishThe satellite is not in a culture folder next to the assembly, or the UI culture has no matching folderCopy the folders with the release; ship the parent culture; set the culture before the first window
One window stays in EnglishThe window comes from another assembly of the applicationAdd that DLL to the project and create its satellite too
Some strings stay in EnglishThey are written in C# code, not in XAML or resourcesMove them into .resx, by hand or with Extractor
Translations are New again after an updatex:Uid values were renamed or regeneratedKeep UIDs stable; import translations from your previous satellites
The preview does not open a windowAn assembly the window needs is missingKeep the dependencies next to the assembly you add; translate in the table meanwhile
A .NET Framework 4.8 application ignores the satellitesThe main assembly is strong-named, and the satellites are not signedSign the satellites with your key in the project
Creating .NET 5–10 satellites failsThe .NET SDK of that version is not installedInstall it, or allow a newer SDK in the project
The localized build crashesA translation breaks a format string or resourceRun Validation; use Crash Finder (Enterprise)
The application is on .NET 1.x–3.5Localizer 10 supports .NET Framework 4.8 and .NET 5–10Use Localizer 9

The WPF Localization sample.

Localizer installs a WPF sample with its project, so you can try every step above without your own build.

  • Two windows: the main window with Print Settings, Profiles, and Resources tabs, and Export Options.
  • English source, a German translation, and a Language menu that restarts the application.
  • Two deliberate defects: a German caption too long for its column, to spot in the preview, and a broken format string.
  • Version 2 of the application to try Scan for Changes.

More about WPF localization.

BAML / binary localization instead of LocBaml

BAML / binary localization works from the compiled application: localizable WPF UI is extracted from BAML resources, translated, validated, and written into standard .resources.dll satellite assemblies. Translators stay outside the source tree, and there is no manual LocBaml-style export and import.

If your project supports the standard WPF UID targets, add and check x:Uid values with them:

msbuild /t:updateuid MyProject.csproj
msbuild /t:checkuid MyProject.csproj
RESX-based WPF localization

Some WPF applications bind UI text to RESX resources rather than relying on BAML. Use this path when translated .resx files must stay in source control and be compiled by the normal Visual Studio, MSBuild, or CI process.

Input:  Resources.resx  Strings.resx  ValidationMessages.resx
Output: Resources.de.resx  Strings.de.resx  ValidationMessages.de.resx
  • Translated resource files stay in the source and build workflow, and developers review the changes in source control.
  • Localization stays tied to compilation: Visual Studio, MSBuild, or CI builds the satellite assemblies.
  • Visual context is weaker than in the BAML / binary workflow.
Reuse existing WPF translations

If previous WPF translations exist, start from the current original build, choose the target languages, and import the translations that still match from:

  • existing .resources.dll satellite assemblies;
  • previous localized WPF binaries;
  • localized .resx files.
What to check in the pseudo-localized WPF build
  • BAML resources are extracted, and x:Uid values are present and stable.
  • Longer text still fits; wrapping and automatic layout behave correctly.
  • FlowDirection and font fallback are acceptable for the target languages.
  • No hardcoded strings were missed, and the application does not crash. If it does, Crash Finder (Enterprise) isolates the resource or translation that causes it.