#1,126 – Localization VII – Preventing Translator from Modifying Certain Elements

By default, when a .csv file is created using the LocBaml tool, the fifth parameter on each line is set to True.  This parameter indicates whether a particular property should be modifiable by the translator.

You can change the value of this modifiable field by setting the Localization.Attributes property for an element.  This property is set to a string of the form “propname(locvalue1 locvalue2) propname(locvalue1 locvalue2)”.

One of the localizability values that you can set is Unmodifiable, to indicate that the specified property should not be modified by the translator.

Below, we set Unmodifiable for various property values.

<Window x:Uid="Window_1" x:Class="WpfApplication1.MainWindow"
        Localization.Attributes="$Content(Unmodifiable) SizeToContent(Unmodifiable)"
        Title="The App" SizeToContent="WidthAndHeight">

    <StackPanel x:Uid="StackPanel_1" Margin="15"
        <Label x:Uid="Label_1" Content="Hello, I like apples."
        <Button x:Uid="Button_1" Content="Learn More" Margin="5"
                Localization.Attributes="$Content(Unmodifiable) Margin(Unmodifiable)"/>

After running the LocBaml tool, we see that the modifiable field is now false for these properties.



#1,125 – Localization VI – Interpreting CSV File That Is Output by LocBaml Tool

As part of the localization process, you can use the LocBaml tool to extract localizable content into a text-based .csv file.

Below is a snapshot of a sample .csv file containing localizable content.


Each line in the .csv file represents a single property of some user interface element.  The line contains the following elements (separated by commas):

  • The name of the BAML resource containing the property
    • (e.g. WpfApplication1.g.en-US.resources:mainwindow.baml)
  • Fully qualified property name, including the element’s UID
    • (e.g. Label_1:System.Windows.Controls.ContentControl.Content)
  • Localization category  (e.g. Button, Label, Text, etc).
  • Whether property is visible to user (T/F).
  • Whether property can or should be modified by translator (T/F)  (defaults to true for all elements)
  • Comments provided for translator  (defaults to blank)
  • Property value  (the thing that should be localized)

#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.


#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.


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.


Double-click the Developer Command Prompt for VS2013 shortcut.


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

msbuild /t:updateuid [yourapplication].csproj


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:


After running msbuild:


#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);
                    Console.WriteLine("{0} - {1}", ci.Name, ci.EnglishName);


#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


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.


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


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



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)
                double num = double.Parse(txt1.Text);
                DateTime dt = DateTime.Parse(txt2.Text);
            catch (Exception xx)

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


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


#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.