Export (0) Print
Expand All

Build World-Ready Device Applications

.NET Compact Framework 1.0
 

Christian Forsberg
businessanyplace.net

June 2004

Applies to:
   Microsoft® .NET Compact Framework 1.0
   Microsoft Visual Studio® .NET 2003

Summary: The Microsoft® .NET Compact Framework functionality for localization (and globalization) is sufficient to create world-ready device applications. A sample application is used to show how to use some of this functionality to translate controls in forms. (6 printed pages)


Download Build World-Ready Device Applications.msi from the Microsoft Download Center.

Contents

International Applications
Localize Anyplace Sample
Code Walk-Through
More Options
Conclusion

International Applications

Many real-world mobile scenarios require applications that are used across many different countries and languages. The requirement to support multiple languages is easier to handle the earlier in the design process it appears. But, as indicated in this article, international support can also be added to existing applications.

The mobile development tools now include good support for building international, or world-ready, applications. This support includes ways to translate the text used in the user interface, the format of numbers and dates, the comparison of strings, and so on. The most important is translating the user interface, which is the focus of the following sample.

Localize Anyplace Sample

The Localize Anyplace sample was created with Microsoft Visual Studio .NET 2003 in C#, and targeting the .NET Compact Framework. The sample shows how to localize controls in a form and consists of a single form, as shown in Figure 1.

Figure 1. Localize Anyplace sample

When the first menu option is selected, the form is translated according to the current language (culture). The current language is the language that you have selected in the Control Panel Regional Settings. When the second option is selected, the form is translated to a language I am currently learning, Brazilian Portuguese, as shown in Figure 2.

Figure 2. Form in Brazilian Portuguese

And when the third menu option is selected, the form is translated into my mother tongue, Swedish, as shown in Figure 3.

Figure 3. Form in Swedish

Now, let's see how this sample was implemented.

Code Walk-Through

The two namespaces that we need to use are:

using System.Globalization;
using System.Reflection;

The System.Globalization namespace include all the functionality to localize (or globalize) applications. The System.Reflection namespace is used by the private method (GetControlName) that retrieves the names of the controls in a form (see below).

To handle the translation of the form, we need two private variables:

private System.Resources.ResourceManager resManager;
private System.Globalization.CultureInfo currentCulture;

The first, the resource manager, is used to retrieve translated strings from the different resource files, and the second holds the currently selected culture information.

The resource manager instance is created in the constructor of the form:

resManager = new System.Resources.ResourceManager("Localize.strings",
                 this.GetType().Assembly);

Note that the first parameter is the "root" name of the resource files. In this case it is the namespace of the form (Localize) followed by a prefix (strings) used in all the resource file names. The default resource file is named "strings.resx", the resource file for Brazilian Portuguese is named "strings.pt-br.resx", and the one for Swedish is named "strings.sv.resx".

The code for the Click event of the first menu option looks like this:

currentCulture = (CultureInfo)CultureInfo.CurrentUICulture.Clone();
TranslateForm();

First the currently selected language (culture) is saved and then the form is translated (see private method TranslateForm below). The code for the second menu option looks like this:

currentCulture = new CultureInfo("pt-br");
TranslateForm();

Here a new culture information instance is created using the code (pt-br) for Brazilian Portuguese (for all culture information codes, see the Visual Studio .NET 2003 help file topic about the CultureInfo Class). Therefore, the code for the third menu option looks like this:

currentCulture = new CultureInfo("sv");
TranslateForm();

Now, let's look at the implementation of the private TranslateForm method:

string s;
foreach (Control ctrl in this.Controls)
  if ((object)(s = resManager.GetString(GetControlName(ctrl),
                                        currentCulture)) != null)
    ctrl.Text = s;

This code iterates through all the controls in the form. The name of each control is used as the name of the string in the resource file for the currently selected culture information. If a string with that name exists, the Text property of the control is updated.

Using the control name as the string name in the resource file simplifies the implementation considerably. There is no need for repeating code for each control that needs to be updated. Also, if the naming of controls is consistent, the same resource string can be used to update all controls with the same name in several forms.

Since only the control names that appear in the resource file are translated, only these controls are affected. This approach makes is possible to add localization of an application after it has been implemented. After the form has been implemented, a few lines of code can be added to each form to perform localization.

An important detail to make this a possibility is to retrieve the name of each control. As there is not Name property available on the Control class, we need a more sophisticated approach. The implementation of the private GetControlName method looks like this:

private string GetControlName(object sourceControl)
{
  FieldInfo[] fi = ((Control)sourceControl).Parent.GetType().GetFields(
    BindingFlags.NonPublic | BindingFlags.Instance |
    BindingFlags.Public | BindingFlags.IgnoreCase);

  foreach (FieldInfo f in fi)
    if (f.GetValue(((Control)sourceControl).Parent).Equals(sourceControl))
      return f.Name;

    return null;
}

This approach is a product of the MVP, Chris Tacke and thanks goes to him. It shows that reflection is a very powerful functionality.

More Options

There are many more options available for localization and globalization of your applications. A culture information instance can be used to retrieve the local format for dates. The local pattern for a short date can be retrieved using the currentCulture.DateTimeFormat.ShortDatePattern property, and to show the current date in the local format, the following code can be used:

MessageBox.Show(String.Format(
  currentCulture.DateTimeFormat.ShortDatePattern, DateTime.Now));

However, note that the DateTimeFormat member is not supported by all cultures.

There are many other DateTimeFormat members to explore. Also, there are many number format members similar to:

currentCulture.NumberFormat.NumberDecimalSeparator

Other options include the possibility to compare strings according to a specific culture (see the Compare method of the String class in the Visual Studio .NET 2003 help file), handling time zones (see the ToUniversalTime topic in the Visual .NET 2003 help file), character encoding, different calendars, and more. To show the current date and time as universal time (UTC), the following code can be used:

MessageBox.Show(DateTime.Now.ToUniversalTime());

Conclusion

The great support for localization and globalization of your application built into the .NET Compact Framework gives you no excuse for not supporting multiple countries, languages, and cultures. Make use of the above sample in your efforts to make your applications available to the world.

Show:
© 2014 Microsoft