#1,112 – Internationalization vs. Localization

Internationalization and localization both deal with adapting software to run as expected under a variety of different languages and/or geographic regions.

Internationalization, typically abbreviated as “i18n”, is the process of making changes to an application so that it could potentially later be adapted to one or more languages or regions.

Internationalization

  • Encompasses the things that you do just once, rather than once per target language/region
  • Must be done before localization
  • Includes activities like
    • Storing strings as Unicode
    • Being aware of regional settings when converting between numeric data and strings
    • Moving localizable resources into “satellite assemblies”
    • Removing hard-code constraints for certain UI elements

Localization, typically abbreviated as “l10n”, is the process of adapting an application for a specific language or region.

Localization

  • Is done once for each targeted language/region
  • Includes activities like
    • Translating strings for a particular language
    • Adjusting UI, as needed, to fit translated elements

#766 – WPF Data Binding Ignores Custom Formatting

You can get the WPF data binding engine to respect the current locale, as specified in the Region applet, by setting the Language property of a FrameworkElement to the language tag that is part of the CurrentCulture property.

Doing this allows you to set up the proper locale in a single line of code and data binding will use the correct rules for formatting dates and floating point numbers for the appropriate language.

This mechanism won’t, however, honor any custom formatting that you specify in the Region applet.  A custom format is anything that you change from the defaults in the Region applet.

766-001

If you want the data binding engine to completely respect all of the settings chosen in the Region applet, you can set the ConverterCulture property to the CurrentCulture, for each binding.

        <TextBlock Text="{Binding BoundDate, ConverterCulture={x:Static glob:CultureInfo.CurrentCulture}}"/>

The glob namespace points to System.Globalization.

766-002

#764 – Current Culture Is Used When Converting Data to A String

The CurrentCulture property of a Thread object indicates a user’s current locale, as set in the Region applet.  This value can normally be thought of as indicating the user’s location.

If you convert either numeric or date data to a string, the formatting used will depend on the current locale, as set in the Region applet and reported by the CurrentCulture property.

For example:

            double d1 = 123.456;
            DateTime date1 = DateTime.Now;

            string output = string.Format("123.456 => {0}\nNow => {1}",
                d1.ToString(),
                date1.ToString());

            MessageBox.Show(output);

If we run this code when our region is set to English (United States), we get:

764-001

But now if we switch our region to French (France) and re-run the application, we get:

764-002

Notice that the decimal point is now displayed as a comma (,) and the date format is dd/mm, rather than mm/dd.

#763 – The Difference Between CurrentCulture and CurrentUICulture

In a WPF application, you have access to two properties that give you information about the user’s culture and language.  They are both properties of a Thread object, which you can access via Thread.CurrentThread.

  • CurrentCulture – Tells you the user’s current locale, as set in the Region applet.  I.e.: Where is the user located?
  • CurrentUICulture – Tells you the native language of the version of Windows that is installed.  I.e.: What language does the user speak?

The user can change CurrentCulture using the Region applet.  It’s used to determine formatting for numeric and date/time strings.

763-001

The user normally can’t change CurrentUICulture without re-installing Windows.  It’s used to know what language to use when displaying text in your application.  (I.e. Which resource files to load).

            CultureInfo ci = Thread.CurrentThread.CurrentCulture;
            lblCurrentCulture.Content = string.Format("CurrentCulture = {0} - {1}", ci.Name, ci.DisplayName);

            ci = Thread.CurrentThread.CurrentUICulture;
            lblCurrentUICulture.Content = string.Format("CurrentUICulture = {0} - {1}", ci.Name, ci.DisplayName);

For example, someone in England might see:
763-002