| Comments

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:

StringFormat with default culture

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:

StringFormat with explicit culture

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:

StringFormat with explicit culture

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!

Please enjoy some of these other recent posts...

Comments