Reputation: 4032
I want to create a Software, where the User can choose between several Languages.
As a start i want to learn how to handle Internationalization, since i have never done that before.
As IDE i use SharpDevelop or #develop, however you would spell it. I want to use C# and WPF, since i'm also learning XAML/WPF at the moment.
So i create a new WPF-Project in ShardDevelop. On the Main Window i create a ComboBox and a TextBlock.
The ComboBox get's two Entries: "German" and "English". The textBlock should show "Hallo Welt!" or "Hello World!", depending on the Language which is selected.
Now comes the part where i get stuck. I guess each language get's a separate file in XML/XAML-Style (Makes sense). Where are these files and how are they and their Content loaded so that the Text of the selected Language is loaded?
I found several examples but all are something about creating Resource-DLL and using some weird program to decompile them back into a csv-file... i don't get it, isn't there an easier way?
I took the next Step. The Text of the TextBlock is now loaded via "{StaticResource Strings.MainForm.hwText}". It looks like this now:
<TextBlock Text="{StaticResource Strings.MainForm.hwText}" />
Also I created one ResourceDictionary for German and one for English which both define the key i used in the TextBlock.
In the Application.Resources Part i load one of the ResourceDictionary's per default.
The Problem now is: How can i "unload" this Dictionary during Runtime and Replace it with the other?
Of course i use the SelectionChange-Event of the ComboBox, but what do i do there?
Problem solved!! Thanks to kmatyaszek
Although i changed the Code of the Event-Handler a bit to my needs:
Uri baseUri = new Uri(AppDomain.CurrentDomain.BaseDirectory);
Uri uri = new Uri(baseUri,"Languages\\lang."+((sender as ComboBox).SelectedItem as ComboBoxItem).Tag.ToString()+".xaml");
if(File.Exists(uri.LocalPath) || File.Exists((uri = new Uri(baseUri,"Languages\\lang.de-DE.xaml")).LocalPath)){
ResourceDictionary dict = new ResourceDictionary();
dict.Source = uri;
this.Resources.MergedDictionaries.Add(dict);
}
Upvotes: 4
Views: 3520
Reputation: 19296
If you created two ResourceDictionary files you can binding by DynamicResource
.
Example:
First resource file (Lang.en-US.xaml):
<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>
</ResourceDictionary>
Second resource file (Lang.pl-PL.xaml):
<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">Login:</system:String>
<system:String x:Key="Password">Hasło:</system:String>
<system:String x:Key="close">Zamknij</system:String>
<system:String x:Key="login">Zaloguj</system:String>
</ResourceDictionary>
Set default language in Application resources:
<Application.Resources>
<ResourceDictionary>
<ResourceDictionary.MergedDictionaries>
<ResourceDictionary Source="Lang.en-US.xaml" />
</ResourceDictionary.MergedDictionaries>
</ResourceDictionary>
</Application.Resources>
Let's say that we have ComboBox like below:
<ComboBox Name="cbLang" Margin="2" SelectionChanged="cbLang_SelectionChanged" >
<ComboBoxItem Content="English" Tag="en-US" />
<ComboBoxItem Content="Polish" Tag="pl-PL" />
</ComboBox>
Code-behind SelectionChanged:
private void cbLang_SelectionChanged(object sender, System.Windows.Controls.SelectionChangedEventArgs e)
{
ResourceDictionary dict = new ResourceDictionary();
switch (((sender as ComboBox).SelectedItem as ComboBoxItem).Tag.ToString())
{
case "en-US":
dict.Source = new Uri("Lang.en-US.xaml", UriKind.Relative);
break;
case "pl-PL":
dict.Source = new Uri("Lang.pl-PL.xaml", UriKind.Relative);
break;
default:
break;
}
this.Resources.MergedDictionaries.Add(dict);
}
And you can binding like this:
<TextBlock Text="{DynamicResource Username}" VerticalAlignment="Center" />
Upvotes: 6