Wednesday, September 29, 2010

Localizing WPF Application

I am currently working in WPF application. Many time I get a requirement from my business side is that they want to localize the application in different languages. But this becomes a problem when the requirement comes in later stage of development. Now there could be lots of effort required to achieve completely localized software. There could be many approaches for localizing WPF application. First of all and very common approach is the use of satellite assembly. Second very new approach is the use of tool called LocBaml from Microsoft. LocBaml is very great tool which helps in easily localizing WPF application.

LocBaml, a sample tool in the Windows SDK. LocBaml help in reducing overhead off manually finding localizable control in XAML and manually apply indirection to all of them. When you invoke LocBaml from the command prompt of visual studio, it complete all the manual task of finding and applying indirection to all the localizable controls.

Below are the Steps of creating a satellite assembly with the help of LocBaml:
1. Set Default culture of an application through .csproj file using <UICulture>--> 
The UICulture element should be added under any or all PropertyGroup elements corresponding
to the build configurations you want to affect (Debug, Release, and so on), or to
a property group unrelated to build configuration so it automatically applies to all of
them. Default setting for en-US(English culture) i shown below:
<Project>

     <PropertyGroup>
<UICulture>en-US</UICulture>
</PropertyGroup>
 </Project>
If you rebuild this project with this setting, you will find en-US folder created in same location of your executable assembly. Inside this folder AssemblyName.resources.dll assembly will get created for en-US culture.

You should also mark your assembly with the assembly-level NeutralResourcesLanguage
custom attribute with a value matching your default UI Culture setting, as follows:
[assembly: NeutralResourcesLanguage(“en-US”,
UltimateResourceFallbackLocation.Satellite)]


2. Create user interface with Localization ID's
Now we need to create user interface and apply Uid directive from XAML namespace to every object element that needs to be localized. The value of each directive should be unique identifier.
sample Uid is "<TextBlock x:Uid="TextBlock_1"> Sample string1 </TextBlock>". Suppose you are going to develop huge application then this could be quite tedious and time taking task if done manually. But thanks to LocBaml which does this automatically by simply invoking one simple command from VS command prompt.

Command as follows: msbuild /t:updateuid ProjectName.csproj. When you run this command, it will add Uid to every XAML element with the unique value. We can add this as a task in msbuild script.

3. Creating a new Satellite assembly with LocBaml:
Now you can run the LocBaml tool from the Windows SDK on a .resources file generated by the build process (found in the obj\debug directory), as follows:
LocBaml /parse AssemblyName.g.en-US.resources /out:en-US.csv. The csv files contains a key value pair for en_US culture. You have to just open file the using excel and provide value against the individual resource keys.
Now point comes in mind how to convert .csv files into a satellite assembly. So below is the command for converting a csv files into a satellite assembly.
LocBaml /generate ProjectName.resources.dll /trans:en-US.csv /cul:en-US. The same can be done for any other culture very easily, just copy  the file for some different culture name and import it similarly using the above command lines. 

4. Set application culture : 
Now our satellite assembly is ready and we have to just set the application culture and get ready to use the resources from the particular culture. 
Below is the code for setting application culture : 
            Thread.CurrentThread.CurrentCulture = new CultureInfo("en-US");
            Thread.CurrentThread.CurrentUICulture = new CultureInfo("en-US");

Thats all we have to do, nothing extra is required for the localization in WPF. It is really very simple and time saving task.