WinForms

WinForms localization for .NET desktop applications.

Translate the forms of your compiled WinForms application in the form editor, check them, and write satellite assemblies for each language. Your EXE and DLLs stay unchanged; nothing is rebuilt. .NET Framework 4.8 and .NET 5–10.

Translated with another tool? 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 form as it is in the build, translated in the form editor 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 LingobitForm editor 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
The assemblies you ship; on .NET 5–10, MyApp.dll
Output
de\MyApp.resources.dll; your EXE and DLLs unchanged
Runtime
.NET loads the satellite of the UI culture
Preview
Forms in the form editor, Full or Safe
On this page

Tutorial

Localize a WinForms application, step by step.

Six steps from your compiled build to localized satellite assemblies.

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 forms 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 forms
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
  1. 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 forms 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 forms
  2. 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

Your build DLL MyApp.dll Project DE FR JA DLL MyApp.dll Forms MainForm ExportOptions Strings.NET resources ExportSummaryFormat FileSaved Detected .NET 8 · 64-bit DLL Your build DLL MyApp.dll Project DE FR JA DLL MyApp.dll Forms MainForm ExportOptions Stringsresources ExportSummaryFormat FileSaved Detected .NET 8 · 64-bit DLL
  1. Your build DLL MyApp.dll Project DE FR JA DLL MyApp.dll Forms MainForm ExportOptions Strings.NET resources ExportSummaryFormat FileSaved Detected .NET 8 · 64-bit DLL Your build DLL MyApp.dll Project DE FR JA DLL MyApp.dll Forms MainForm ExportOptions Stringsresources ExportSummaryFormat FileSaved Detected .NET 8 · 64-bit DLL

Project MyApp.dll MainForm ExportOptions Resources Harbor Supply Quantity: 12 Create Cancel New Order Neue Bestellung Customer: Kunde: SourceGerman New Order Neue Bestellung Customer: Kunde: Project MyApp.dll MainForm ExportOptions Harbor Supply Quantity: 12 Create Cancel New Order Neue Bestellung Customer: Kunde: SourceGerman New Order Neue Bestellung Customer: Kunde:
ProjectDEFRJAMyApp.dllFormsMainFormResources 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.dllFormsMainFormResources 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 MainForm ExportOptions Resources Harbor Supply Quantity: 12 Create Cancel New Order Neue Bestellung Customer: Kunde: SourceGerman New Order Neue Bestellung Customer: Kunde: Project MyApp.dll MainForm ExportOptions Harbor Supply Quantity: 12 Create Cancel New Order Neue Bestellung Customer: Kunde: SourceGerman New Order Neue Bestellung Customer: Kunde:
  2. ProjectDEFRJAMyApp.dllFormsMainFormResources 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.dllFormsMainFormResources 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…

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.
MyApp · German ! An unexpected error occurred. OK Which translation causes it? German version: error Which translation causes it? All translations Run 1Error Run 2Works Run 3Error Run 4Works … Found Source Order {0} was saved. Translation Bestellung {1} wurde gespeichert. {1} instead of {0} makes the application fail. MyApp · German ! An unexpected error occurred. OK Which translation causes it? German version: error Which translation? All translations Run 1Error Run 2Works Run 3Error Run 4Works … Found Source Order {0} was saved. Translation Bestellung {1} wurde gespeichert. {1} instead of {0} makes the application fail.
  1. 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.
  2. MyApp · German ! An unexpected error occurred. OK Which translation causes it? German version: error Which translation causes it? All translations Run 1Error Run 2Works Run 3Error Run 4Works … Found Source Order {0} was saved. Translation Bestellung {1} wurde gespeichert. {1} instead of {0} makes the application fail. MyApp · German ! An unexpected error occurred. OK Which translation causes it? German version: error Which translation? All translations Run 1Error Run 2Works Run 3Error Run 4Works … Found Source Order {0} was saved. Translation Bestellung {1} wurde gespeichert. {1} instead of {0} makes the application fail.

Project MyApp.dll MainForm 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 MainForm ExportOptions Create Localized Files EXE MyApp.exe · .dll unchanged DEde\ FRfr\ JAja\ Run Localized Application Neue Bestellung Kunde: Harbor Supply Erstellen Abbrechen
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:
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 MainForm 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 MainForm ExportOptions Create Localized Files EXE MyApp.exe · .dll unchanged DEde\ FRfr\ JAja\ Run Localized Application Neue Bestellung Kunde: Harbor Supply Erstellen Abbrechen
  2. 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:
  3. 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 resource name: 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 resource name.
Translated earlier MyApp.exe de\ DE MyApp.resources.dll fr\ FR MyApp.resources.dll Project Not Translated Imported DE FR MyApp.exe Forms Resources 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 Forms Resources 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 resource name: 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 resource name.
  2. Translated earlier MyApp.exe de\ DE MyApp.resources.dll fr\ FR MyApp.resources.dll Project Not Translated Imported DE FR MyApp.exe Forms Resources 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 Forms Resources 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

Localizable forms keep their text in resources; languages ship as satellite assemblies.

When a form's Localizable property is true, the designer keeps its text, sizes, and positions in the form's .resx, and the build compiles them into the assembly. Lingobit translates those resources in the form editor and writes them into a satellite assembly for each language. At startup, .NET loads the forms from the folder of the current UI culture.

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:
  • Set Localizable = true on every form. A form left at the default keeps its text in code: Lingobit lists the form but has no text to translate.
  • Messages in code belong in a .resx file too; Lingobit Extractor finds hard-coded C# and VB strings.

Full shows the form as your application does; Safe works without its controls.

The Full editor loads each form with its real assemblies and third-party controls, as it looks in your application. The Safe editor works where those controls cannot be loaded, for example on a translator's computer: it replaces the complex controls with stand-ins, and the whole form stays visible and translatable. If Full cannot open a form, Localizer switches to Safe and says so in Output. The editor runs in a separate process, so a failing assembly does not close Localizer.

Form editor · MainFormFullSafe New Order Customer: Harbor Supply Quantity: 12 Create Cancel Item Qty Price Bolts 24 0.15 Stand-in Item Qty Price Full shows the real third-party control, as in your application. Safe puts a stand-in where its assembly is missing. For example, a translator's computer may not have it. Form editor · MainFormFullSafe New Order Customer: Harbor Supply Quantity: 12 Create Cancel Item Qty Price Bolts 24 0.15 Stand-in Item Qty Price Full shows the real third-party control, as in your application. Safe puts a stand-in where the assembly is missing. For example, a translator's computer may not have it.

Reference

Culture decides which resources load.

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

UI culture de-DE: each string is looked up on its own de-DE\not shippedde\neutralMyApp.exeCustomer:—Kunde:Customer:Quantity:—Menge:Quantity:Cancel—missingCancel Neue BestellungKunde:Menge:Cancel Cancel is missing in de\,so it comes from the neutralresources; the rest is German Each string on its own de-DE\not shippedde\neutralMyApp.exeCustomer:—Kunde:Customer:Quantity:—Menge:Quantity:Cancel—missingCancel Neue BestellungKunde:Menge:Cancel
  • Resources are looked up one by one. A string missing in de\ comes from the neutral resources; it does not break the form.
  • 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.

Set the culture yourself before the first form is created:

  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 Application.Run creates the main form.
  4. Restart to switch after the user picks another language.
[STAThread]
static void Main()
{
    var culture = CultureInfo.GetCultureInfo(LoadSavedLanguage() ?? "en-US");
    CultureInfo.DefaultThreadCurrentCulture = culture;
    CultureInfo.DefaultThreadCurrentUICulture = culture;

    ApplicationConfiguration.Initialize();
    Application.Run(new MainForm());
}

Do and don't.

Do

  • Set Localizable = true on every form and user control.
  • Localize the build you release, and add every assembly that holds forms.
  • Keep control names stable between versions: translations are matched to them.
  • Use AutoSize and layout panels, so longer German text has room.
  • Ship the parent culture folder, such as de\.

Don't

  • Set text in code after InitializeComponent: it stays in English.
  • Rename controls after localization has started without a reason.
  • Build UI text in code from pieces of strings.
  • Set the culture after the first form is created.

Troubleshooting.

Symptoms, causes, and what to do
SymptomLikely causeWhat to do
A form has no text to translateIts Localizable property is false, so the text is in codeSet Localizable = true in the designer, rebuild, and run Scan for Changes
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 form
A control shows as a stand-in in the Safe editorIts assembly is not on this computer, as on a translator's computerCopy the assemblies next to the program to see the real control in the Full editor; the text stays translatable in Safe 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 WinForms sample.

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

  • The same application for .NET 8 and .NET 10, with a small German starter translation.
  • Version 2 of the application to try Scan for Changes: new options, updated captions, a reused message, and a removed option.

More about WinForms localization.

Binary or RESX localization for WinForms

Binary localization is the recommended workflow for most WinForms teams once forms are localizable: it works from the release build, keeps translators outside the source tree, and writes standard .resources.dll satellite assemblies.

Use direct RESX localization when translated .resx files must stay in the source tree and the normal Visual Studio or MSBuild build creates the satellites. The trade-off:

  • Localization stays tied to development and compilation.
  • Translators may need developers to get the latest RESX files.
  • Less visual context: the Full editor is not available for RESX files.
  • Testing translated UI is slower: the translated files usually have to be compiled first.
Reuse existing WinForms translations

After the current original files and target languages are added, Lingobit looks for existing localized output in the standard .NET locations and offers to import the translations that still match:

  • previous .resources.dll satellite assemblies;
  • localized .resx files;
  • previous localized binaries or build output.
What to check in the pseudo-localized WinForms build
  • Forms are visible in the editor, and their strings are actually localizable.
  • Longer text still fits, and the layout does not break.
  • 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.