Click here to Skip to main content
Click here to Skip to main content

MultiLanguage Applications

, 12 Oct 2003
Rate this:
Please Sign up or sign in to vote.
Describes how to make your applications support multiple languages without rewriting code.

Introduction

On an Internet-linked world, is not too hard that our applications travel may be to Madagascar or something. Besides, as the time pass, the software working teams are more heterogeneous as our possible clients.

In this article I describe in a fast way, the basis for the treatment of globalization in our applications.

Lets understand globalization as the fact of allowing an application behave correctly in any culture defined inside an operating system. In general, like in Microsoft(R) Windows(R), we realize that we can set some aspects choosing a culture, using the option Language from the Control Panel.

This culture determines the way in which the numbers are displayed on screen, the date format, the format for negative numbers, the language for some emergent messages, etc.

In general, the cultures' identification has been standardized is such a way that with a single string, each one is well established. This string is formed by two components separated by a hyphen. The first of them identifies the base for a given culture and the second one specifies the possible culture variations derived from the application of such a culture in a given region or country. Thus, some valid culture name examples are:

  • "es-CO" - For the culture determined by the Spanish in Colombia
  • "fr-FR" - For the culture determined by the French in France
  • "fr-CA" - For the culture determined by the French in Canada
  • "es" - For the culture determined by the English in General

Three important details:

  1. Some culture names are only described by one component... this is no more than a generalization for a given name.
  2. As you can see, the name of the region or country always is written with CAPS and is composed (in general) by the two first letters of it.
  3. When there is not an explicit specification for a culture inside an application (.NET application), the default culture for it will be: "" (empty string) or "en" which is the same in this case.

Background

On the .NET framework there are two special objects which allow us to globalize our applications:

  1. ResourceManager (System.Resources.ResourceManager)
  2. CultureInfo (System.Globalization.CultureInfo)

The main idea is that with the CultureInfo object we get access to all the information and methods related with cultures in a system and with the ResourceManager we get access to the resources related to a specific culture.

How is this? For instance, if we are going to make our application available in English as well as in Spanish, it doesn't mean that we have to write two different code list. The idea is having two resources files (one for each language, containing the equivalent strings).

Using the code

Let's get into the code creating the globalized HelloWorld which could divide two numbers (this is in order to see how the multi-language exceptions handling would be).

So, we want our program detect the actual machine configuration (specially the culture settings) and allow to change the language in run time. This is: if Windows(r) setting is configured as Spanish, the program will start in Spanish; nevertheless, at any time we could change the language to English.

Ok, now we start creating a Windows Application Project and add two textboxes and two command buttons to the main form:

The textboxes are intended to write two numbers for the program and divide them (in order to generate a multi-language exception when we try to divide by zero). The first brings up the Hello World message box and the second one makes the division of the numbers.

Now, we're going to add the two files we'll use. One, for the culture "es-CO" and the other one for the default culture: English:

The default source file will be called myRes.resx. The file for the "es-CO" culture MUST be called like this: <default file name>.<culture>.resx. In this case: myRes.es-CO.resx. In this way if we were to include a resource file for "fr-CA", we would have to add the myRes-fr-CA.resx file.

Once the files have been added to the project, they look like this:

The relevant columns are name and value. For each string we need in our program, we have to add a dictionary pair name-value. For instance, we want the button's text property change as well as the error messages, etc. The important thing is that same resources name have to be defined in all the files:

We can see that same names (though different values) are included in both tables... values for comment, type and mimetype aren't relevant for this application.

Now, we can add a culture attribute to our form, in order to handle it easily; but first, let's include the appropriate namespaces to work comfortably:

using System.Resources;
using System.Globalization;

After this, we can add the attribute I just mentioned, just after the declaration of the visual attributes (buttons, textboxes, etc.):

private CultureInfo culture;

In order to get the initial machine culture configuration just at the beginning of the application, we use the following command when the form is created:

culture=CultureInfo.CurrentCulture;

You might want to change the language of the application in runtime... so let's add some more controls:

In this way, when a radio button is checked, the culture must be changed. For example, if the Spanish flag is checked the code would be like this:

culture=CultureInfo.CreateSpecificCulture("es-CO");

Now... how to change the captions and messages??

ResourceManager rm=new 
   ResourceManager("HelloWorldGlobed.myRes",typeof(Form1).Assembly);
string btnHello=rm.GetString("btnHello",culture);

We create a ResourceManager object whose constructor receives in this example two parameters: the base name for the resource file (i.e. the namespace of the project containing the resources file and the root of the file name), and the assembly from which the resource is called; it is easy to identify it by using the reserved word typeof and specifying the name of the form and its Assembly attribute.

Then, we can use the rm object to get the required string by telling it the name of the string resource (as we named it in the table), and the culture for which the ResourceManager have to seek (if our culture object actually is "es-CO", rm will search in the file myResx.es-co.resx; otherwise, it will search in myResx.resx).

Points of interest

  • I used the "division by zero" example to show how to handle exceptions in various languages, but actually, .NET knows how to divide by zero. Thus if you divide by zero, you get as a returned value, "Infinite", which is not an error. Though, in my code, I threw an exception when division by zero is detected.
  • When you create some resources files, when building your applications, a DLL called <projectname>.resources.dll is created for each resource file, and stored in the resource/debug folder inside a subfolder called as the culture identification (in this example a folder called es-CO was automatically created inside the release folder, with a file inside it called HelloWorldGlobed.resources.dll). So don't forget to attach that folder when deploying your application!!!
  • Globalization is not only for Windows applications... I have created Web Services and ASPX pages with this support; but in ASPX pages you have to be careful and ingenious with the state management in order to communicate the language specification between pages (using query strings) or between roundtrips of the same page (using view state, because security in this case is not an issue, so something like a session variable will be a waste).

License

This article has no explicit license attached to it but may contain usage terms in the article text or the download files themselves. If in doubt please contact the author via the discussion board below.

A list of licenses authors might use can be found here

Share

About the Author

War Nov

United States United States
No Biography provided

Comments and Discussions

 
Questioncc PinmemberBợm Nhậu12-Sep-12 18:05 
QuestionWindows Multilanguage form displays junk Pinmemberhr_prathibha27-Feb-12 21:54 
GeneralMy vote of 4 Pinmemberashishkumar00815-Sep-11 20:36 
GeneralMulti language support Pinmemberakul12319-Feb-11 22:45 
GeneralRe: Multi language support Pinmemberprincedominh19-May-11 6:02 
GeneralMy vote of 3 PinmemberMember 37298898-Dec-10 1:03 
QuestionEverything works fine, but not after install?? Pinmembersilentje27-May-09 3:58 
Generalconvert one language into other format PinmemberMember 339317119-Jan-09 22:04 
Questionwhat about multi form ??? Pinmembersurvcopt13-Aug-08 2:39 
QuestionCould I do all this automatic? PinmemberJP_Amber30-Jul-06 23:45 
AnswerRe: Could I do all this automatic? PinmemberJohn448-Aug-06 9:57 
QuestionDate Format Problem PinmemberSivagnanam28-Feb-06 1:12 
GeneralHelp Pinmembersreejith ss nair18-Sep-05 22:21 
GeneralCulture support for Bengali Pinmemberbuddymanish12-Sep-05 20:26 
Generalthanks PinmemberKanagu_INDIAN1-Aug-05 20:22 
GeneralRe: thanks Pinmemberbrocklyn14-Jul-08 4:14 
GeneralThanks PinmemberAmey Pingle22-Jul-05 22:05 
GeneralGlobalization( multilanguage application) using Visual Basic .NET and ORacle 10g Pinmemberashit_barot21-Mar-05 20:03 
GeneralNeed for advice in number of .resx files Pinmemberlonifasiko14-Jul-04 22:45 
GeneralRe: Need for advice in number of .resx files Pinsussleoh19-Sep-04 20:44 
GeneralRe: Need for advice in number of .resx files Pinmemberclockhar23-Oct-04 12:54 
QuestionHow many rsource files per application? Pinmemberlonifasiko14-Jul-04 22:31 
AnswerRe: How many rsource files per application? Pinmemberwarnov27-Nov-04 6:06 
AnswerRe: How many rsource files per application? Pinmemberbrocklyn14-Jul-08 4:18 
Generalnew line character problem Pinmembere11even17-Jun-04 7:53 

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Rant Rant    Admin Admin   

Use Ctrl+Left/Right to switch messages, Ctrl+Up/Down to switch threads, Ctrl+Shift+Left/Right to switch pages.

| Advertise | Privacy | Terms of Use | Mobile
Web03 | 2.8.141216.1 | Last Updated 13 Oct 2003
Article Copyright 2003 by War Nov
Everything else Copyright © CodeProject, 1999-2014
Layout: fixed | fluid