The first time I came aware of this issue was when reading a post by Portuguese MVP Paulo Morgado on the App Hub Forums:
If all the emulator settings are set to “Portuguese (Portugal)” (both interface as all regional settings), how come when I use an IValueConverter on any Binding expression, the “culture” parameter has a “en-US” CultureInfo?…
To properly research on the subject, I created a small app with two TextBlock controls that show the Thread.CurrentThread.CurrentCulture and Thread.CurrentThread.CurrentUICulture current values, and a third TextBlock with an IValueConverter that basically returns the culture.Name he is using, and the result was quite surprising!
Here is the code for my CultureDebugValueConverter class, implementing an IValueConverter:
public class CultureDebugValueConverter : IValueConverter{ public object Convert(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture) { return culture.Name; } public object ConvertBack(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture) { throw new NotImplementedException(); }}
Notice that no conversion is actually being made (the value parameter isn’t even being used), it just returns the “culture.Name” value from it.
Here’s the main ContentPanel on the MainPage.xaml:
<StackPanel x:Name="ContentPanel" Grid.Row="1" Margin="12,0,12,0"> <TextBlock Style="{StaticResource PhoneTextSubtleStyle}">CurrentCulture</TextBlock> <TextBlock Text="{Binding CurrentCulture}" Style="{StaticResource PhoneTextTitle2Style}" /> <TextBlock Style="{StaticResource PhoneTextSubtleStyle}">CurrentUICulture</TextBlock> <TextBlock Text="{Binding CurrentUICulture}" Style="{StaticResource PhoneTextTitle2Style}" /> <TextBlock Style="{StaticResource PhoneTextSubtleStyle}">Converter Culture</TextBlock> <TextBlock Text="{Binding Converter={StaticResource CultureDebugValueConverter}}" Style="{StaticResource PhoneTextTitle2Style}" /></StackPanel>
As you can see, the last TextBlock just sets the Binding.Converter to a StaticResource of CultureDebugValueConverter type.
This is the remaining code placed on MainPage.xaml.cs:
public partial class MainPage : PhoneApplicationPage{ public MainPage() { InitializeComponent(); this.DataContext = this; } public string CurrentCulture { get { return Thread.CurrentThread.CurrentCulture.Name; } } public string CurrentUICulture { get { return Thread.CurrentThread.CurrentUICulture.Name; } }}
Finally, I started the emulator, changed all the regional settings to “Portuguese (Portugal), and this is what I got after running the app:
So the real question right now is: If the operating system interface, the CurrentCulture, and the CurrentUICulture are all set to “pt-PT”, from where did that “en-US” came from?
There is no trivial reason for this behavior, and to completely understand it, we first need to know how the “culture” parameter on IValueConverter.Convert method works; on the documentation, you can read the following: * The culture is determined in the following order:
- The converter looks for the ConverterCulture property on the Binding object.
- If the ConverterCulture value is null, the value of the Language property is used.
Given that I didn’t set the Binding.ConverterCulture property, this means it will fallback to the FrameworkElement.Language, which in turn has this in the docs:
The default is an XmlLanguage object that has its IetfLanguageTag value set to the string “en-US”**
We have finally found the “guilty” one!!!
Now that we know this, we can fix it just by setting the Page.Language property! The fixed code should look something like this:
public MainPage(){ Language = System.Windows.Markup.XmlLanguage.GetLanguage(Thread.CurrentThread.CurrentUICulture.Name); InitializeComponent(); this.DataContext = this;}
If you look closely on the 3rd line, you’ll see the Language property set to a XmlLanguage instance created with the CurrentUICulture.Name.
Be aware that for this to work, you must set the Language property before the InitializeComponent method gets invoked!
And here’s the final result:
I honestly don’t know the reason for this strange behavior, but this is a problem to account for if you have localization needs for your Windows Phone app!
The demo project I created and used for this article can be downloaded from here!