I recently got a note about a nagging issue in using StringFormat in XAML binding expressions and how it doesn’t honor the current user’s culture settings. This is true that there is an issue in that it doesn’t in WPF or Silverlight. If you don’t know what I’m talking about, Silverlight introduced the ability to use StringFormat in data binding expressions (WPF has had this since 3.5 SP1) so you could do some formatting in-line in your binding. Like this:
1: <TextBlock Text="{Binding Path=CurrentDate, StringFormat=Current Timestamp is: \{0:G\}}" />
This would result in text that would be formatted directly using your string Formatter without the need for code-behind or any generic ValueConverter. This is a very helpful feature for formatting UI values as well as in some cases replacing ValueConverters for simple tasks.
The problem is that StringFormat isn’t honoring the user’s culture settings. Take for example this complete XAML:
1: <StackPanel x:Name="FooContainer">
2:
3: <TextBlock x:Name="CultureInfo" />
4: <TextBlock x:Name="UICultureInfo" />
5:
6: <TextBlock Text="{Binding Path=CurrentDate, StringFormat=Current Timestamp is: \{0:G\}}" />
7:
8: <TextBlock x:Name="CostField" Text="{Binding Path=Cost, StringFormat=Cost is: \{0:c\}}" />
9:
10: <toolkit:GlobalCalendar />
11:
12: </StackPanel>
This is being bound to a simple object that exposes two properties for the purposes of demonstration: CurrentDate (DateTime) and Cost (double). Using my standard US-English settings and regional preferences the output would be:
Now, let me tell my Silverlight app that I have a different culture information. I can do this without having to force a language pack installation of sorts and completely change my machine. Adding the culture/uiculture params to the <object> tag does the trick. I’ll change it to “de-de” for German. Here is the new output:
What?! Even thought the settings recognize a different culture, StringFormat is not doing what I expect. I would have expected a different date display for German settings (d.m.yyyy) and a different currency display instead of dollars.
Unfortunately this is an issue in StringFormat right now, but there is a simple workaround that if you are creating a localized app you can add to your code that shouldn’t affect your default language settings either. In my constructor I add this line of code:
1: this.Language = XmlLanguage.GetLanguage(Thread.CurrentThread.CurrentCulture.Name);
This tells the markup system to use the current culture settings as the UI language. XmlLanguage is a part of the System.Windows.Markup namespace, so ensure you call that out explicitly or add a using statement. Now refreshing my German settings sample I get:
as expected. Changing (or removing the explicit setting of culture in my <object> tag) back to my default culture settings results in my US-English preferences being used and no need for me to change the XAML.
Hope this helps!
I had a similiar problem recently. Your solution works for simple scenarios, but when introducing more complex controls things get a little more tricky. In particular I had issues with ChildWindow (mine where created in code, but I think XAML are the same) and the nested controls within not inheriting the Language from the parent.
Best, Mark
var culture = CultureInfo.CurrentCulture;
var lang = XmlLanguage.GetLanguage(culture.IetfLanguageTag);
FrameworkElement.LanguageProperty.OverrideMetadata(typeof(FrameworkElement), new FrameworkPropertyMetadata(lang));
Thank you Tim for your blog - it saved my day (not to talk about the days of the last week)
Thank you very much.
@Houman: "<object> tag" means that in your web project, is the ASPX page that contains the reference to your Silverlight app. This reference is inside an normal HTML <object> tag. Well, the trick is that you can use the tags like
<param name="uiculture" value="es-ES"/>
<param name="culture" value="es-ES"/>
to specify the culture right there, instead of doing it programatically (another option).
I hope it helps.
I want to display the numeric values in linear axis of a chart. I have a configuration screen where user selects the option about the display format of y-axis values. These options are as under
0, 0.00, 0%, 0.00%, 0€, 0.00€
Below is the xaml of the dependent axis style where i can set the display format of y-axis.
==================================================================
<toolkit:LinearAxis x:Name="depAxis" Orientation="Y" ShowGridLines="True" ExtendRangeToOrigin="True">
<toolkit:LinearAxis.AxisLabelStyle>
<Style TargetType="toolkit:AxisLabel">
<Setter x:Name="axisFormat" Property="StringFormat" Value="{}{0:C}"/>
</Style>
</toolkit:LinearAxis.AxisLabelStyle>
</toolkit:LinearAxis>
==================================================================
Q. How can I display the user configured string format using styles.
Isn't the best way to solve the problem?
You can add this class for common functionalities:
public class ViewBase : PhoneApplicationPage
{
public ViewBase()
{
this.Language = XmlLanguage.GetLanguage(Thread.CurrentThread.CurrentCulture.Name);
}
...
}
And then, the root element of all your xaml will be something like:
<local:ViewBase
xmlns:local="clr-namespace:WP.UI.View"
>
. . .
</local:ViewBase>
Thanks Tim