Wed, December 1, 2004, 12:48 PM under
MobileAndEmbedded
So
we looked at how you change the language in a Compact Framework scenario and how we can read the current locale. The most popular reason for which users change language, is to read the text of your UI in their own language (profound statement or what? :-)
The .NET way of doing that is using
RESX files and resource dlls (a.k.a.
satellite assemblies). The process is very similar to the desktop scenario, but the file formats are incompatible (and that will be the case for CF 2.0 too). There is a lot of info on using RESX files, so I won't go into any detail here. (In a nutshell, in the designer you can set the
Localizable property of your forms to true and then change the strings once per language; this creates a RESX file per form per language and, on compilation, all RESX of a language are rolled into a
resources dll. When deploying your app, place each .resources dll in its own folder under your app's directory, naming each directory as per the two-letter language code. At runtime, the CLR picks up automatically the system's locale and hence which resources dll to load and life is goodness).
Note that the
SatelliteContractVersion attribute is supported at compile time but does not work at runtime so don't use it. Essentially you must deploy all your satellite dlls with your exe every time you roll the version (unless the only change is the revision in which case they are considered compatible as per the CF rules).
Also note that, if you need additional strings for translation (e.g. MessageBox strings), they have to reside in their own resx file (that you create manually and must include as an embedded resource). To retrieve these you need to explicitly use the
ResourceManager (i.e.
like this).
Finally, you may find the
CFResgen tool useful. It allows for conversion between txt/resx/resources files (tip: save your txt file as utf-8).
So I leave you with my approach:
I do not use the RESX files created by the forms, and in fact I leave Form.Localizable to false. Instead, I maintain one
text file of name/value pairs and whenever I need a string in my app I add it to the txt file. The implication is that I set the Text for all controls outside the InitializeComponent method (ctor or OnLoad as appropriate). I then run cfresgen on the text file to get a
single RESX file, which is the one included in my project as a resource. I send it to the translators and they send me back a translated RESX file that I also add to my project; from those, the compiler spits out the satellite assemblies. Note that our translators use a localisation tool that works great with RESX files, but we had one who did not have access to the tool, so sending them the txt file and then performing the conversion to RESX on our end worked out great. The attraction to the aforementioned method is the simplicity of dealing with a single txt file from which everything else stems.