![]() |
License: The Code Project Open License (CPOL)
WPF LocalizationBy Sacha Barberrecently at work I was asked to look into Localization techniques when working with WPF/XAML. There are some excellent sources around that cover the various different techniques such asthis excellent article which outlines the following techniquesUsing LocbamlLocbaml is a localization tool that M |
All-Topics
|
||||||||||||
|
Advanced Search Add to IE Search |
|
|
|
||||||||||||||||
recently at work I was asked to look into Localization techniques when working with WPF/XAML. There are some excellent sources around that cover the various different techniques such as
this excellent article which outlines the following techniques
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.
Here are the steps involved with doing this
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
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
An alternative approach is to not use Locbaml at all and simply use RESX (resource files).
Here are the steps involved with doing this
public App()
{
HelloWorldUsingResXFiles.Properties.Resources.Culture = new CultureInfo(”fr-CA”);
}
Advantages Of This Method
Disadvantages Of This Method
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.
<Label Content=”{DynamicResource label1}”/>
In my main App I simply have the following ResourceDictionary
1: <ResourceDictionary xmlns=”http://schemas.microsoft.com/winfx/2006/xaml/presentation” 2: xmlns:x=”http://schemas.microsoft.com/winfx/2006/xaml” 3: xmlns:system=”clr-namespace:System;assembly=mscorlib”> 4: <system:String x:Key=”label1″>label1</system:String> 5: <system:String x:Key=”label2″>label2</system:String> 6: <system:String x:Key=”label3″>label3</system:String> 7: <system:String x:Key=”label4″>label4</system:String> 8: <system:String x:Key=”label5″>label5</system:String> 9: </ResourceDictionary>
Then in the App file I have the following
1: <Application x:Class=”LooseXAML.App” 2: xmlns=”http://schemas.microsoft.com/winfx/2006/xaml/presentation” 3: xmlns:x=”http://schemas.microsoft.com/winfx/2006/xaml” 4: StartupUri=”Window1.xaml”> 5: 6: <Application.Resources> 7: <ResourceDictionary> 8: <ResourceDictionary.MergedDictionaries> 9: <ResourceDictionary Source=”Dictionary_en-US.xaml” /> 10: </ResourceDictionary.MergedDictionaries> 11: </ResourceDictionary> 12: </Application.Resources> 13: 14: </Application>
Then somewhere I may reference these resources like
1: <Label Content=”{DynamicResource label1}”/>
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
1: <ResourceDictionary xmlns=”http://schemas.microsoft.com/winfx/2006/xaml/presentation” 2: xmlns:x=”http://schemas.microsoft.com/winfx/2006/xaml” 3: xmlns:system=”clr-namespace:System;assembly=mscorlib”> 4: <system:String x:Key=”label1″>french label1</system:String> 5: <system:String x:Key=”label2″>french label2</system:String> 6: <system:String x:Key=”label3″>french label3</system:String> 7: <system:String x:Key=”label4″>french label4</system:String> 8: <system:String x:Key=”label5″>french label5</system:String> 9: </ResourceDictionary>
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
Disadvantages Of This Method
| You must Sign In to use this message board. | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
General
News
Question
Answer
Joke
Rant
Admin
Use Ctrl+Left/Right to switch messages, Ctrl+Up/Down to switch threads.
|
PermaLink |
Privacy |
Terms of Use
Last Updated: 11 Sep 2009 Editor: Sean Ewington |
Copyright 2009 by Sacha Barber Everything else Copyright © CodeProject, 1999-2010 Web19 | Advertise on the Code Project |