Multilanguage Application in WPF
Posted by Viral Sarvaiya on May 7, 2011
From this 2 link we can get batter idea of Globalization and Localization,
http://msdn.microsoft.com/en-us/library/ms752337.aspx
http://msdn.microsoft.com/en-us/library/ms788718.aspx
Here i demostrate very simple way for multiple language application in WPF.
here i make a simple login form in wpf with 2 language English and French Button.
Step 1: Open Visual studion, Create New Project of WPF give name “WPFMultiLanguage”.
so now you have 2 .xaml file App.xaml and MainWindow.xaml,
Step 2: New we add new folder named “Resources” for Multiple Language.
Step 3: Add resource files
To add resource file named “StringResources.xaml”, right click to Resource folder => Add => Resource Directory (See Image below)
So your file is as like
<ResourceDictionary xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" > </ResourceDictionary>
I have added one namespace which points to mscorlib, and named it as system and now add resource string to StringResources.xaml
so StringResources.xaml as below
<ResourceDictionary xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:system="clr-namespace:System;assembly=mscorlib"> <system:String x:Key="Username">Username</system:String> <system:String x:Key="Password">Password</system:String> <system:String x:Key="close">close</system:String> <system:String x:Key="login">login</system:String> <system:String x:Key="French">French</system:String> <system:String x:Key="English">English</system:String> </ResourceDictionary>
Now add another resource directory for French language named “StringResource.fr-CA.xaml”
put there French string resuouce and give same key name as per above file,
so StringResource.fr-CA.xaml as below.
<ResourceDictionary xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:system="clr-namespace:System;assembly=mscorlib"> <system:String x:Key="Username">Nom d'utilisateur</system:String> <system:String x:Key="Password">Mot de passe</system:String> <system:String x:Key="close">Fermer</system:String> <system:String x:Key="login">connexion</system:String> <system:String x:Key="French">Française</system:String> <system:String x:Key="English">En anglais</system:String> </ResourceDictionary>
Step 4: Add Resource file to window.
Now its time to add resource file to Mainwindow page.
for that in the MainWindow.xaml file design the login page and put 2 button for the language transfer.
For display content and text from resource file, use DynamicResource.
for that i have made 1 function that add dictionaries directly to window resources and in click event of the button for language transfer i set culture for that.
so MainWindow.xaml as below.
<Window x:Class="WPFMultiLanguage.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="MainWindow" Height="350" Width="525">
<Grid Background="Beige" >
<Grid.ColumnDefinitions>
<ColumnDefinition></ColumnDefinition>
<ColumnDefinition></ColumnDefinition>
</Grid.ColumnDefinitions>
<Grid.RowDefinitions>
<RowDefinition></RowDefinition>
<RowDefinition></RowDefinition>
<RowDefinition></RowDefinition>
<RowDefinition></RowDefinition>
</Grid.RowDefinitions>
<TextBlock Name="Username" Text="{DynamicResource Username}" VerticalAlignment="Center" HorizontalAlignment="Right" Margin="0,24,18,38"></TextBlock>
<TextBox Name="txtuser" Width="100" Height="30" Grid.Column="1" Grid.Row="0" VerticalAlignment="Center" HorizontalAlignment="Left"></TextBox>
<TextBlock Name="Password" Text="{DynamicResource Password}" Grid.Column="0" Margin="0,24,18,38" Grid.Row="1" VerticalAlignment="Center" HorizontalAlignment="Right"></TextBlock>
<PasswordBox Name="txtpass" Width="100" Height="30" Grid.Column="1" Grid.Row="1" HorizontalAlignment="Left" VerticalAlignment="Center" />
<Button x:Name="btnLogin" Width="100" Height="40" VerticalAlignment="Top" HorizontalAlignment="Right"
Click="btnLogin_Click" Content="{DynamicResource login}" Grid.Row="2" Grid.Column="0" Padding="10" />
<Button x:Name="btnClose" Width="100" Height="40" VerticalAlignment="Top" HorizontalAlignment="Left"
Click="btnClose_Click" Content="{DynamicResource close}" Grid.Row="2" Grid.Column="1" Padding="10" />
<Button x:Name="btnEnglish" Width="100" Height="40" VerticalAlignment="Bottom" HorizontalAlignment="Right"
Click="btnEnglish_Click" Content="{DynamicResource English}" Grid.Row="3" Grid.Column="0" Padding="10" />
<Button x:Name="btnFrench" Width="100" Height="40" VerticalAlignment="Bottom" HorizontalAlignment="Left"
Click="btnFrench_Click" Content="{DynamicResource French}" Grid.Row="3" Grid.Column="1" Padding="10" />
</Grid>
</Window>
and MainWindow.xaml.cs as below.
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;
using System.Threading;
namespace WPFMultiLanguage
{
/// <summary>
/// Interaction logic for MainWindow.xaml
/// </summary>
public partial class MainWindow : Window
{
public MainWindow()
{
InitializeComponent();
SetLanguageDictionary();
}
private void SetLanguageDictionary()
{
ResourceDictionary dict = new ResourceDictionary();
switch (Thread.CurrentThread.CurrentCulture.ToString())
{
case "en-US":
dict.Source = new Uri("..\\Resources\\StringResources.xaml", UriKind.Relative);
break;
case "fr-CA":
dict.Source = new Uri("..\\Resources\\StringResource.fr-CA.xaml", UriKind.Relative);
break;
default:
dict.Source = new Uri("..\\Resources\\StringResources.xaml", UriKind.Relative);
break;
}
this.Resources.MergedDictionaries.Add(dict);
}
private void btnLogin_Click(object sender, RoutedEventArgs e)
{
if (txtuser.Text.Trim() == "")
{
MessageBox.Show("Please Enter Username");
//If u want to set resource from code behind then use below code
//FindResource("<Resource Key Name>").ToString()
return;
}
if (txtpass.Password.Trim() == "")
{
MessageBox.Show("Please Enter Password");
return;
}
if (txtuser.Text.Trim() == txtpass.Password.Trim())
{
MessageBox.Show("Sucess");
}
}
private void btnClose_Click(object sender, RoutedEventArgs e)
{
this.Close();
}
private void btnEnglish_Click(object sender, RoutedEventArgs e)
{
System.Globalization.CultureInfo cultureInfo = new System.Globalization.CultureInfo("en-US");
Thread.CurrentThread.CurrentCulture = cultureInfo;
SetLanguageDictionary();
}
private void btnFrench_Click(object sender, RoutedEventArgs e)
{
System.Globalization.CultureInfo cultureInfo = new System.Globalization.CultureInfo("fr-CA");
Thread.CurrentThread.CurrentCulture = cultureInfo;
SetLanguageDictionary();
}
}
}
Now run the solution
english is by default so first time when you run code it display in english language
and then click to French button it display in French.
Enjoy…..






Ernst said
Is there any way to suppres XAMLParseException when a x:key is missing and using the FallBackValue. We have the ResourceDirectory separate so the user can create the language file, but want a default value if they forget to supply the string.
raza said
it give resource file missing :/ how can I resolved it
Hugo said
It’s good way to create application with neutral language only and after add satellite assemblies. That will allow you to create translation without changing your application source. LSACreator is simple tool that helps with that. There is a free edition with full functionality.
http://tbs-apps.com/lsacreator/