sábado, 16 de junho de 2012

Localizable forms in C# or How to translate your C# application in the right way

As my first post I will try to give some tips of how to use localizable forms in C#, this is particularly useful if you want to give the user the option to select multiple languages in your application.
Visual Studio gives you some help to you in this task by letting you use the Language property of a given Form. Setting this option to a language different from default let you edit all the strings in your form and Visual Studio automatically creates a .resx file with the strings that you translated. This method allows you to change the position and size of the components in the Form (because phrases have different sizes in different languages), but unfortunately it not allows you to add or remove any of the components in the Form.

By default when the application starts it automatically selects the language file of the current system language if that exists, if not it select the one marked as default. So if want to allow your user to set the language, save the language that it selected in a file and restore the configs when the program loads.
After this little introduction, let’s see a little example:
I created a form with 3 Buttons and a Label to show how to change the language on the fly.
But first let’s make or application speaks different languages =D
First go to the Form’s language property and change it to the language that you want to translate your application.
After you selected the language, change the position of the components and their properties as you want. I just translated all the text to portuguese, and set the label in a different position.
Save the file.
I then changed the language to English (United States) and made it say that now our application is true American. Don’t forget to save after you finished your modifications.
Change the language option of the form back to (Default)
Now the interesting part begins, first let’s create two methods, the first one called ChangeLanguage as the name says, change the language used by the application. But there is a problem in doing that, the application doesn’t automatically refreshes the resources included in the form, so then the second method RefreshResources take it’s places.
   1: //change the language in real time 

   2: private void ChangeLanguage(string lang)

   3: {

   4:     CurrentLocale = new CultureInfo(lang);

   5:     foreach (Control c in this.Controls)

   6:     {

   7:         ComponentResourceManager resources = new ComponentResourceManager(typeof(Form1));

   8:         resources.ApplyResources(c, "$this");

   9:         RefreshResources(this, resources);

  10:     }

  11: }


  13: //refresh all the controls e sub-controls of the form 

  14: private void RefreshResources(Control ctrl, ComponentResourceManager res)

  15: {

  16:     ctrl.SuspendLayout();

  17:     res.ApplyResources(ctrl, ctrl.Name, CurrentLocale);

  18:     foreach (Control control in ctrl.Controls)

  19:         RefreshResources(control, res); // recursion

  20:     ctrl.ResumeLayout(false);

  21: }

The first function receives a string that defines the language to be set and calls the refresh method. Microsoft uses a standard that is 2 lowercase letters to identify the language plus two uppercase letters to define the country with a minus signal between they. Some examples are:

pt-BR (Brazilian Portuguese)

en-US (American English)

en-GB (Britain English)

The list of all the codes can be found here.

The second function update the resources recursively by using the SuspendLayout() and ResumeLayout() methods, this is necessary because you can’t apply the resource file without the layout suspend. This fuction works even if you have controls inside controls, like components inside a tab.

I will try to give the complete project for all the examples that I made.

So here is this sample project : VS 2010 Project

I think that’s ok for a first post, a not complicated thing to do, but useful if you boss call you and say that software need to be translated to some foreign language.

So goodbye my friends and remember to code until …

Um comentário:

  1. Hay man , i need some help, i have a similar situation, but mine doesn't work, and i have an MDIParent (default window) with child forms populating in it, and i cant seem to get it translated