Tuesday, March 16, 2010

quick c# localization by java properties files and reflection

A quick way to localize C# application is given by this example.
There is a trivial windows form application and a LabelManager project.

This is a sketch of how it works.
Visual Studio generates, for any form, two files. The second one is automatically filled with name ending by .designer.cs, that should not be edited, and that contains a InitializeComponent() function that assign values to widget according to visual development.

Assignment to Text element are in the form:

this.label1.Text = "This label is in english";

You know that the full path of the label1 element (by namespace.classname) is:

WindowsformsApplication1.SampleForm.label1.Text

So to localize this label in any language an international.properties file can contain the localized values espressing the fully qualified element property, preceded by a locale string, and followed by the desired assignment, as follows:

it.WindowsFormsApplication1.SampleForm.label1.Text=questo testo è in italiano
ru.WindowsFormsApplication1.SampleForm.label1.Text=Этот текст на русском языке

The App.config shoould contains the value (ru or it) for the current localization, in order to choose the version (italian or russian, in this case).
Note: the international.properties is encoded in utf-8 to manage special chars.

The call (not the definition) to InitializeComponent() must be followed by an UpdateUi(this) call that will change those properties according to locale and to the international.properties file, using a LabelUtils package.

Some script file can be useful to generate easily structure of the international.properties.
Until now I just used stuffs like this bash command:
for i in `find . | grep ".cs$"`; do echo $i; cat $i | egrep "Text ="; done;

(you need a bash shell interpreter)

This approach is original, and may require much more tests, and efficiency improvement, particularly about exceptions handling.

In few steps to use this approach :
create your forms and assign text values as usual by Visual Studio.
At any time (also when your application is completely done), detect all the properties assignable by strings, for example using some bashing.
Create an international.properties files assigning values to any properties by locale.
Assign locale in the App.config
Be sure that international.properties will be contained in the build directory, for example adding some copy directive in the AfterBuild target section of the vs build file.


Suggestions and contributions are welcome.


p.s. I mentioned about bash and the sample command:
for i in `find . | grep ".cs$"`; do echo $i; cat $i | egrep "Text ="; done;

the '`' may not be available in all the keyboards layout.
Change keyboard layout, or use the following command instead:
for i in $(find . | grep ".cs$"); do echo $i; cat $i | egrep "Text ="; done;

Ciao.
Tony

No comments: