Localization is the process of customizing your application for a given culture and locale. The language needs to be associated with the particular region where it is spoken, and this is done by using locale (language + location). For example: fr is the code for French language.
Software localization is the process of adapting software to both the culture and language of an end user, from standards of measurement to video and graphic design. It involves not only translation, but also design and UX changes to make software look and feel natural to the target user.
Resources in . resx files. Unlike text files, which can only store string resources, XML resource (. resx) files can store strings, binary data such as images, icons, and audio clips, and programmatic objects.
Step 1: Open Visual Studio > File > New > Project. In the Project Types pane, choose the language of your choice (Visual C# or Visual Basic). In the Templates pane, choose Windows Application. Choose a name and location for the project and click OK.
strings.resx
.System.Threading
and System.Globalization
Run this code:
Console.WriteLine(Properties.strings.Hello);
It should print "Hello".
Now, add a new resource file, named "strings.fr.resx" (note the "fr" part; this one will contain resources in French). Add a string resource with the same name as in strings.resx, but with the value in French (Name="Hello", Value="Salut"). Now, if you run the following code, it should print Salut:
Thread.CurrentThread.CurrentUICulture = CultureInfo.GetCultureInfo("fr-FR");
Console.WriteLine(Properties.strings.Hello);
What happens is that the system will look for a resource for "fr-FR". It will not find one (since we specified "fr" in your file"). It will then fall back to checking for "fr", which it finds (and uses).
The following code, will print "Hello":
Thread.CurrentThread.CurrentUICulture = CultureInfo.GetCultureInfo("en-US");
Console.WriteLine(Properties.strings.Hello);
That is because it does not find any "en-US" resource, and also no "en" resource, so it will fall back to the default, which is the one that we added from the start.
You can create files with more specific resources if needed (for instance strings.fr-FR.resx and strings.fr-CA.resx for French in France and Canada respectively). In each such file you will need to add the resources for those strings that differ from the resource that it would fall back to. So if a text is the same in France and Canada, you can put it in strings.fr.resx, while strings that are different in Canadian french could go into strings.fr-CA.resx.
It's quite simple, actually. Create a new resource file, for example Strings.resx
. Set Access Modifier
to Public
. Use the apprioriate file template, so Visual Studio will automatically generate an accessor class (the name will be Strings
, in this case). This is your default language.
Now, when you want to add, say, German localization, add a localized resx file. This will be typically Strings.de.resx
in this case. If you want to add additional localization for, say, Austria, you'll additionally create a Strings.de-AT.resx
.
Now go create a string - let's say a string with the name HelloWorld
. In your Strings.resx
, add this string with the value "Hello, world!". In Strings.de.resx
, add "Hallo, Welt!". And in Strings.de-AT.resx
, add "Servus, Welt!". That's it so far.
Now you have this generated Strings
class, and it has a property with a getter HelloWorld
. Getting this property will load "Servus, Welt!" when your locale is de-AT, "Hallo, Welt! when your locale is any other de locale (including de-DE and de-CH), and "Hello, World!" when your locale is anything else. If a string is missing in the localized version, the resource manager will automatically walk up the chain, from the most specialized to the invariant resource.
You can use the ResourceManager
class for more control about how exactly you are loading things. The generated Strings
class uses it as well.
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)
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.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With