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.
- 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.
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.
- Set
Localizable = trueon 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
.resxfile 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.
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.
- 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 servesde-DE,de-AT, andde-CH; addde-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:
- List the languages you ship from the culture folders next to the application.
- Read the saved choice or a command-line switch; fall back to the source language.
- Set
CurrentUICulturebeforeApplication.Runcreates the main form. - 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 = trueon 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
AutoSizeand 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.
| Symptom | Likely cause | What to do |
|---|---|---|
| A form has no text to translate | Its Localizable property is false, so the text is in code | Set Localizable = true in the designer, rebuild, and run Scan for Changes |
| The application stays in English | The satellite is not in a culture folder next to the assembly, or the UI culture has no matching folder | Copy 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 editor | Its assembly is not on this computer, as on a translator's computer | Copy 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 satellites | The main assembly is strong-named, and the satellites are not signed | Sign the satellites with your key in the project |
| Creating .NET 5–10 satellites fails | The .NET SDK of that version is not installed | Install it, or allow a newer SDK in the project |
| The localized build crashes | A translation breaks a format string or resource | Run Validation; use Crash Finder (Enterprise) |
| The application is on .NET 1.x–3.5 | Localizer 10 supports .NET Framework 4.8 and .NET 5–10 | Use 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.dllsatellite assemblies; - localized
.resxfiles; - 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.
Related paths
- WPF / BAML — The same satellite workflow for WPF windows.
- .NET Resources — Translate .resx files when they must stay in source control.
- Visual localization — The form editor, Full and Safe.
- Migration — Bring translations from your existing satellites.