I just can\'t seem to get localization to work.
I have a class library. Now I want to create resx files in there, and return some values based on the threa
Great answer by F.Mörk. But if you want to update translation, or add new languages once the application is released, you're stuck, because you always have to recompile it to generate the resources.dll.
Here is a solution to manually compile a resource dll. It uses the resgen.exe and al.exe tools (installed with the sdk).
Say you have a Strings.fr.resx resource file, you can compile a resources dll with the following batch:
resgen.exe /compile Strings.fr.resx,WpfRibbonApplication1.Strings.fr.resources
Al.exe /t:lib /embed:WpfRibbonApplication1.Strings.fr.resources /culture:"fr" /out:"WpfRibbonApplication1.resources.dll"
del WpfRibbonApplication1.Strings.fr.resources
pause
Be sure to keep the original namespace in the file names (here "WpfRibbonApplication1")
A fix and elaboration of @Fredrik Mörk answer.
strings.resx
Resource file to your project (or a different filename)Access Modifier
to Public
(in the opened strings.resx
file tab)Hello
, value Hello
)Visual Studio auto-generates a respective strings
class, which is actually placed in strings.Designer.cs
. The class is in the same namespace that you would expect a newly created .cs
file to be placed in.
This code always prints Hello
, because this is the default resource and no language-specific resources are available:
Console.WriteLine(strings.Hello);
Now add a new language-specific resource:
strings.fr.resx
(for French)Hello
, value Salut
)The following code prints Salut
:
Thread.CurrentThread.CurrentUICulture = CultureInfo.GetCultureInfo("fr-FR");
Console.WriteLine(strings.Hello);
What resource is used depends on Thread.CurrentThread.CurrentUICulture
. It is set depending on Windows UI language setting, or can be set manually like in this example. Learn more about this here.
You can add country-specific resources like strings.fr-FR.resx
or strings.fr-CA.resx
.
The string to be used is determined in this priority order:
strings.fr-CA.resx
strings.fr.resx
strings.resx
Note that language-specific resources generate satellite assemblies.
Also learn how CurrentCulture
differs from CurrentUICulture
here.
ResourceManager and .resx are bit messy.
You could use Lexical.Localization¹ which allows embedding default value and culture specific values into the code, and be expanded in external localization files for futher cultures (like .json or .resx).
public class MyClass
{
/// <summary>
/// Localization root for this class.
/// </summary>
static ILine localization = LineRoot.Global.Type<MyClass>();
/// <summary>
/// Localization key "Ok" with a default string, and couple of inlined strings for two cultures.
/// </summary>
static ILine ok = localization.Key("Success")
.Text("Success")
.fi("Onnistui")
.sv("Det funkar");
/// <summary>
/// Localization key "Error" with a default string, and couple of inlined ones for two cultures.
/// </summary>
static ILine error = localization.Key("Error")
.Format("Error (Code=0x{0:X8})")
.fi("Virhe (Koodi=0x{0:X8})")
.sv("Sönder (Kod=0x{0:X8})");
public void DoOk()
{
Console.WriteLine( ok );
}
public void DoError()
{
Console.WriteLine( error.Value(0x100) );
}
}
¹ (I'm maintainer of that library)
In my case
[assembly: System.Resources.NeutralResourcesLanguage("ru-RU")]
in the AssemblyInfo.cs prevented things to work as usual.
In addition @Fredrik Mörk's great answer on strings, to add localization to a form do the following:
"Localizable"
to true
Language
property to the language you want (from a nice drop-down with them all in)Edit: This MSDN article on Localizing Windows Forms is not the original one I linked ... but might shed more light if needed. (the old one has been taken away)
In addition to @Eric Bole-Feysot answer:
Thanks to satellite assemblies, localization can be created based on .dll/.exe files. This way:
There is a little known tool called LSACreator (free for non-commercial use or buy option) which allows you to create localization based on .dll/.exe files. In fact, internally (in language project's directory) it creates/manages localized versions of resx files and compiles an assembly in similar way as @Eric Bole-Feysot described.