Using Locbaml

Locbaml is a localization tool that Microsoft have as a free download, available from http://msdn.microsoft.com/en-us/library/ms771568.aspx. This tool may be used to translate compiled XAML (binary XAML, BAML) resources into a CSV and may be used to translate a CSV file into a new Dll.

Copy <PROJECT NAME>.resources.dll from step 10, which was placed on C: to the folder created in step 11

Create a constructor for App class like follows:

public App()
{
string culture = “fr-CA”; //Where this is the culture you want to use
System.Threading.Thread.CurrentThread.CurrentUICulture =
new System.Globalization.CultureInfo(culture);
System.Threading.Thread.CurrentThread.CurrentCulture =
new System.Globalization.CultureInfo(culture);
}

Advantages Of This Method

You can do it at the end of the project

You don’t have to interfere with your main Assembly to install new cultures

Disadvantages Of This Method

· It is laborious and error prone

· Not well suited for teams of developers as a new CSV file is created each time you use the LocBaml tool, so you need to know what was different between newly exported CSV file and the translation CSV file

Using RESX Files

An alternative approach is to not use Locbaml at all and simply use RESX (resource files).

Here are the steps involved with doing this

Create normal WPF App

There will already be a resx file within the Properties folder, so simply add a string value to that for the text you want to localize. Make sure to select public from Access Modifier drop down

Within any Window that you want to use localized text, add a clr-namespace such as

xmlns:properties=”clr-namespace:HelloWorldUsingResXFiles.Properties”

Hook up a items text to a resource file text, like

<Button Margin=”10″ Name=”button1″

Content=”{x:Static properties:Resources.MainButtonText}”></Button>

8.Copy and paste the existing resx file within the Properties folder to a new file with the following name 9.Resources.nn-XX.resx OR Resources.nn.resx10.Modify the App.cs file to include whatever culture should be used, for example

As all cultural resource files are in Main Assembly, may make doing automated build harder

Another Way : Use Dynamically Loaded Assemblies With ResourceDictionaries

I just couldn’t help but think there was a better way, so I had a think about this, and it seems just like the way skins are applied in WPF. You wire certain control properties to DynamicResources where a new XAML file (the skin) is loaded which effects the control that is referencing the resource. So I had a think about it and thought why not do the same for Localization strings. So that’s what I did. Here is the idea

Keep a Main Assembly which expects to get localization resources from a ResourceDictionary, and then at runtime load in an extra Assembly which contains just the ResourceDictionaries for the matching CurrentCulture where the application is running.

The loaded Assemblies ResourceDictionaries will be used to replace the default one within the main Assembly.

Create normal WPF App, and use a ResourceDictionary for strings

Use MergedDictionary in App.resources

Make sure any localizable controls using a DynamicResource like

<Label Content=”{DynamicResource label1}”/>

Create a new culture assembly with a sensible name, such as Culture_fr-CA

For assembly created in step 4, create mirror image ResourceDictionary that matches the original Assemblies ResourceDictionary. but with translated strings

Compile the culture assembly to some folder under main Assemblies bin\debug folder. This demo assumes this folder is called “CultureFiles”

When main app runs, get current culture and Load the matching Assembly from disk

From the currently loaded Culture Assembly, extract the ResourceDictionary

Using the extracted ResourceDictionary, replace the current Application.MergedResources dictionary with the newly extracted culture ResourceDictionary

All controls that refer to the Dynamic resources should be ok now with new cultural strings

So that is all pretty standard stuff. Next I created a new Assembly with a single ResourceDictionary in it. I am using the culture string as part of the Assembly name and or the actual ResourceDictionary

The actual ResourceDictionary MUST contain the name items as the main Assembly

From here I compile this assembly and put it somewhere visible from the main Assembly, such as bin\debug\CultureFiles

From there is just a question of loading the seperate culture Assemblies and extracting the contained ResourceDictionary and replacing the current Main Assemblies ResourceDictionary. Thus forcing all resourced referencing controls to update with the new resource data.

There is a small demo application that demonstrated this approach here which you may test by clicking on the the fr-CA listbox item

Before

After

But you MUST ensure that your current culture is set to French-CANADA via control panel for it to work. This means change region Options AND languages. If you don’t do this the CurrentCulture will not be correct for the demo code to work.

Advantages Of This Method

Very easy to implement

Disadvantages Of This Method

Lots of different Assemblies to manage

Culture Assemblies ResourceDictionary entries must match Main Assembly otherwise a lookup may fail at runtime

Comments and Discussions

Hi,I'm currently working on a bunch of tools which follows the LocBaml workflow.Instead of using cvs files for translations I will use xml files.With the main tool you can setup projects to combine multiple c# or vb projects into one 'solution'.Then you decide into which languages you want to translate your assemblies.You can split and merge this main xml file into files with a subset of languages - one for every team member who does translations. These translations can be done with an seperate editor that has a lot of filter capabilities.Dictionaries for auto translation will be supported as well. You can implement your own auto translation sources by implementing an .net interface (to use some online translation service for example).A the end you click a generate button to get the satelite dll's.

By this tools the disadvantages you mentioned for LocBaml should be solved.

I'm still in the beginning of this project, but as soon as I have a working version I will host it on codeplex.com.So have a look for bloc.codeplex.com in the near future.As soon as I find some more time, I will write an small article for CodeProject as well.