Archive

Posts Tagged ‘binding’

Setting the Culture in WPF Applications

May 20, 2010 3 comments

The culture of an application not only specifies its language but also more specific culture related things such as date (e.g., mm/dd/yy or dd/mm/yyy) and number formatting (1.23 or 1,23) and default currency.

Usually your application gets its culture from the operating system. In some cases, you might want to set it yourself. The most obvious way to set a culture pragmatically in C# is as follows.

xmlLanguage = XmlLanguage.GetLanguage("nl-BE");
Thread.CurrentThread.CurrentCulture = xmlLanguage;
Thread.CurrentThread.CurrentUICulture = xmlLanguage;

There are two caveats to this. First of all, this only sets the culture for a specific thread. To my knowledge, there is no way to set the culture application-wide so you will have to set the culture for each thread you create. If you only need the culture to localize the user interface, I suppose this is not required since the UI runs on a single thread anyway.

I thought this was all there was to it, until I used a binding in XAML which had a culture specific formatting string:

<TextBlock Text="{Binding Order.Price, StringFormat='{0:F2}'}"/>

Depending on the culture, the ‘F2’ formatting string produces “1.23” or “1,23”. The problem was that it did not format as I expected based on the previously set culture. By adding a DebugConverter to the binding, I was able to inspect which culture was used by the binding. It was ‘en-US’ instead of ‘nl-BE’, the former being the default culture used by a binding. Apparently, the culture used by the binding and passed to its (optional) converter, if not set explicitly by assigning the Binding.ConverterCulture property, can be set globally at the top element of the XAML document with the xml:lang attribute.

Alternatively, you can set the culture globally as follows (see this post on msdn).

FrameworkElement.LanguageProperty.OverrideMetadata(
    typeof( System.Windows.FrameworkElement ),
    new FrameworkPropertyMetadata(XmlLanguage.GetLanguage("nl-BE") ) );

From now on, each binding will use the nl-Be culture by default.