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.resxstrings.fr.resxstrings.resxNote 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 trueLanguage 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.