I have a WPF application in which I support multiple langauges. I can change the language runtime, as I load different sets of resource dictionaries containing the string resources upon change of language.
private void UpdateLoadedLanguages(object sender, SelectionChangedEventArgs e)
{
RemoveLoadedLanguages();
ResourceDictionary aResourceDictionary = new ResourceDictionary();
ResourceDictionary bResourceDictionary = new ResourceDictionary();
ResourceDictionary cLanguageResourceDictionary = new ResourceDictionary();
Language selectedLanguage = (Language) e.AddedItems[0];
switch (selectedLanguage)
{
case Language.enUS:
a.Source = new Uri("pack://application:,,,/[Projecta];component/src/Helpers/Language.en-US.xaml");
b.Source = new Uri("pack://application:,,,/[Projectb];component/src/resources/Language.en-US.xaml");
c.Source = new Uri("pack://application:,,,/[Projectc];component/src/resources/Language.en-US.xaml");
break;
case Language.nlNL:
a.Source = new Uri("pack://application:,,,/[Projecta];component/src/Helpers/Language.nl-NL.xaml");
b.Source = new Uri("pack://application:,,,/[Projectb];component/src/resources/Language.nl-NL.xaml");
c.Source = new Uri("pack://application:,,,/[Projectc];component/src/resources/Language.nl-NL.xaml");
break;
default:
a.Source = new Uri("pack://application:,,,/[Projecta];component/src/Helpers/Language.en-US.xaml");
b.Source = new Uri("pack://application:,,,/[Projectb];component/src/resources/Language.en-US.xaml");
c.Source = new Uri("pack://application:,,,/[Projectc];component/src/resources/Language.en-US.xaml");
break;
}
App.Current.Resources.MergedDictionaries.Add(aResourceDictionary );
App.Current.Resources.MergedDictionaries.Add(bResourceDictionary );
App.Current.Resources.MergedDictionaries.Add(cResourceDictionary );
}
A resource dictionary with the translations typically looks like this:
<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="DefaultApplicationTitleString">Title</system:String>
<system:String x:Key="DefaultDoneString">Done</system:String>
<system:String x:Key="DefaultCancelString">Cancel</system:String>
<system:String x:Key="DefaultDescriptionString">Description unknown</system:String>
<system:String x:Key="LanguageSelectionString">Language</system:String>
<system:String x:Key="AisleString">Aisle</system:String>
<system:String x:Key="LevelsString">levels</system:String>
</ResourceDictionary>
When I use one of the strings as defined above like directly below it works perfect.
Title="{DynamicResource DefaultApplicationTitleString}"
But with a converter like this ...
public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
{
string text = (string) Application.Current.FindResource("DefaultDescriptionString");
if (value != null)
{
string temp = (string) value;
char[] stringSeparators = { 'A', '.', '-' };
string[] stringElements= temp.Split(stringSeparators, StringSplitOptions.RemoveEmptyEntries);
string aisleString = (string) Application.Current.FindResource("AisleString");
string levelsString = (string) Application.Current.FindResource("LevelsString");
text = aisleString + " " + stringElements[1] + ", " + levelsString + " " + stringElements[2] + " - " +
stringElements[3];
}
return text;
}
... that I use like this ...
<TextBlock Text="{Binding Id, Converter={StaticResource ItemIdToTextConverter}}" />
... then my strings aren't updated when I change the language. If the property that I convert is updated on its viewModel then the language change does happen.
So my question: Does anyone have a solution for me where also my strings as a result of converters are updated on a language change?
My guesses for a solution are:
- force an update of all frameworkelements that use a resource (How would I do this?)
- or maybe do something with DynamicResourceExtenstion (I found this question: Return a dynamic resource from a converter, however I do not understand the explanation of the DynamicResourceExtension. So is this the way to go? If so, how would I implement this?)