#1,124 – Localization V – Extracting Localizable Content Using LocBaml

Once you’ve generated UIDs for user interface elements and obtained the LocBaml tool, the next step in the localization process is to extract localizable content from the BAML data in your compiled DLL.

The steps are as follows:

  • Copy the locbaml.exe into the same directory as your application’s .exe file
  • Open a Visual Studio 2013 command prompt
  • Navigate to directory containing your .exe (e.g. \bin\Release, with \en-US sub-directory containing satellite assembly)
  • Enter: locbaml.exe /parse .\en-US\[application].resources.dll  (where en-US is the default culture)

After running this command, you’ll see a .csv file show up in the same directory (e.g. WpfApplication1.resources.csv).  The CSV file will contain a list of localizable content.

1124-001

#1,123 – Localization IV – Download and Build the LocBaml Tool

After generating UIDs for all user interface elements in your project, the next step is to extract elements that need to be localized (i.e. given values for a specific language) into an external file.  This file can be passed to people doing the localization.

To extract localizable data, you need a tool called LocBaml.  This tool is made available by Microsoft, but not distributed with Visual Studio.

To get a copy of the LocBaml tool:

  • Download LocBaml project (for .NET 4) from here
  • Open LocBaml project and rebuild using Release|x86 configuration, targeting a .NET Framework version that matches your main project

#1,122 – Localization III – Updating UIDs after Initial Creation

In order to localize your application, you must assign unique UIDs to all elements.  This is done with the msbuild command and the /t:updateuid parameter.  You normally do this before you start localizing your application.

If you later add user interface elements to your application, you’ll have some elements that don’t have the x:Uid attribute.  You can check to see if there are elements that are missing this attribute using the /t:checkuid parameter on the msbuild command.

1122-001

At this point, you can use the /t:updateuid parameter with the msbuild command again to add the x:Uid attribute to any elements that are missing it.  This command will also fix any duplicated UIDs.

You can use the /t:updateuid parameter as often as you like.  Each time you run msbuild with this parameter, you’ll update UIDs for all user interface elements.

 

#1,121 – Localization II – Assigning UIDs to All Localizable Elements

After adding a UICulture tag, the next step in localizing a WPF is to assign a UID (unique identifier) to each element in each of your XAML files.  These UIDs will later be used to localize/translate the XAML.

To start, press the Windows key, type Visual Studio, and click on the Visual Studio Tools icon.

1121-001

Double-click the Developer Command Prompt for VS2013 shortcut.

1121-002

In the command prompt, navigate to the directory containing your project (.csproj) file.  Enter the command:

msbuild /t:updateuid [yourapplication].csproj

1121-003

Open your project and then open one of your .xaml files.  You’ll see that each element now has a x:Uid attribute that wasn’t there before.  Each element will have a unique value for this attribute.

Before running msbuild:

1121-004

After running msbuild:

1121-005

#1,120 – Getting a List of All Supported Cultures

You can get a full list of all cultures supported by .NET using the CultureInfo.GetCultures static method.  (In System.Globalization namespace).

Below is a code sample that dumps out a little bit of information about all known cultures.

            CultureInfo[] cultureList = CultureInfo.GetCultures(CultureTypes.AllCultures);
            foreach (CultureInfo ci in cultureList.OrderBy(cult => cult.Name))
            {
                if (ci.IsNeutralCulture)
                    Console.WriteLine("{0} (neutral) - {1}", ci.Name, ci.EnglishName);
                else
                    Console.WriteLine("{0} - {1}", ci.Name, ci.EnglishName);
            }

1120-001

#1,119 – Localization I – Set UICulture Tag

The first step in localizing an application is to add a UICulture tag to your project file, as shown below.  This tells the compiler that you’ll be localizing your application and specifies a default culture to use.

To make this change:

  • Open your project file (e.g. .csproj) in a text editor
  • Add the following tag within the first PropertyGroup:
    • <UICulture>en-US</UICulture>
  • Save your change
  • Open the project in Visual Studio
  • Rebuild the project

1119-002

The application will run as it did before, but the compiled versions of your XAML files (BAML) are now located in a separate DLL–a satellite assembly.  We can see this by comparing the contents of the \bin directory before and after the change.

Before making the change, we just had an .exe file.

1119-001

After the change, the main directory contains the .exe file and a new en-US sub-directory.

1119-003

In the en-US folder is a DLL containing the BAML.

1119-004

 


Note: You’ll also need to set the NeutralResourcesLanguage attribute in AssemblyInfo.cs.

#1,118 – An Example of Input that Obeys CurrentCulture

One step in internationalizing an application is to respect the current regional settings when reading numeric or date/time values from a user.

If you are parsing user-entered text and converting to numeric or date/time data, the Parse methods associated with individual data types respect the current regional settings.

Below, we read text from two TextBox controls, interpreting the first value as a double and the second as a DateTime using the corresponding Parse method.

        private void Button_Click(object sender, RoutedEventArgs e)
        {
            try
            {
                double num = double.Parse(txt1.Text);
                DateTime dt = DateTime.Parse(txt2.Text);
            }
            catch (Exception xx)
            {
                MessageBox.Show(xx.ToString());
            }
        }

On an English/US system, we can enter the data as “1.1” and “5/2/12”.  The date is interpreted as May 2nd.

1118-001

For French/France, we must enter “1,1” for the double.  “5/2/12” is interpreted as Feb 5th.

1118-002

#1,117 – Internationalization II – Obey CurrentCulture for Input

The first step in internationalizing an application is to ensure that your application honors the user’s current regional settings, as reflected by the CurrentCulture property of the application’s main thread.

Current culture impacts not only how you display the following types of data, but also how the user inputs this data:

  • Numeric data
  • Date/time values

These values are typically stored internally as numeric (e.g. double, int) or DateTime values.  The values exist in memory in a culture-agnostic form.  You need to worry about regional settings only when you display a value to the user or receive input from the user.

In .NET, if you use the Parse method of a numeric or date/time type to convert a user-supplied string to the internal type, the parse operation will expect the string to be in a format that is valid for the current region.

 

#1,116 – An Example of Output that Obeys CurrentCulture

The first step in internationalizing an application is to respect the current regional settings when outputting numeric, date/time, or currency values.

Below is an example of an application that displays numeric and date/time values, using the ToString method for instances of double and DateTime.

    <StackPanel>
        <StackPanel Margin="10" Orientation="Horizontal">
            <StackPanel>
                <Label Name="lbl1"/>
                <Label Name="lbl2"/>
                <Label Name="lbl3"/>
                <Label Name="lbl4"/>
                <Label Name="lbl5"/>
            </StackPanel>
            <StackPanel>
                <Label Name="lbl6"/>
                <Label Name="lbl7"/>
            </StackPanel>
        </StackPanel>
        <Button Content="Gen Strings" Padding="10,5"
                Margin="10"
                Click="Button_Click"/>
    </StackPanel>

In the Click event handler, we set the labels’ content.

        private void Button_Click(object sender, RoutedEventArgs e)
        {
            DateTime rightNow = DateTime.Now;

            lbl1.Content = rightNow.ToString();
            lbl2.Content = rightNow.ToString("d");  // short date
            lbl3.Content = rightNow.ToString("D");  // long date
            lbl4.Content = rightNow.ToString("t");  // short time
            lbl5.Content = rightNow.ToString("T");  // long time

            double num = 123456.789;
            lbl6.Content = num.ToString();
            lbl7.Content = num.ToString("n");
        }

With regional settings set to English (United States), the output looks like this:

1116-001

If I change my region to French (France), the formatting changes as expected.

1116-003

1116-004

#1,115 – Internationalization I – Obey CurrentCulture for Output

The first step in internationalizing an application is to ensure that your application honors the user’s current regional settings, as reflected by the CurrentCulture property of the application’s main thread.

Current culture impacts the display of the following:

  • Numeric data
  • Date/time values
  • Currency values

All of these values are typically stored internally as numeric (e.g. double, int) or DateTime values.  These values exist in memory in a culture-agnostic form.  You only need to worry about regional settings when you display a value to the user.

In .NET, if you use the ToString method on a numeric or date/time object, with or without formatting strings, the resulting string will correctly reflect the current regional settings.

If you’re using data binding to convert numeric or date/time data to strings, you need to manually set the Language property on each window or page to force data binding to use the culture correctly.