Click here to Skip to main content
65,938 articles
CodeProject is changing. Read more.
Articles
(untagged)

Binding with Respect to CurrentCulture

0.00/5 (No votes)
29 Jun 2015 1  
Binding with respect to CurrentCulture

Introduction

You can find a lot of questions about this issue on the internet. There are also a lot more answers about this - but which one is best? If you understand the problem, you can simply choose the best one. I will try to explain how it works inside. At first, let’s define what is actually the problem with Binding and values formatting.

If you suppose that your application will be used in a multi-language environment, you would like to format the values in the application according to regional customs. Moreover, the default regional formatting customs may be modified by a user of a computer where the application is running.

In Czech environment, it is common to format decimal number as following: 10 000,5. In English speaking countries, it would be: 10,000.5. Nevertheless there can be a user (maybe a Czech programmer) who would like to use the English formatting and therefore he has changed the default formatting of the decimal numbers to the English one in its Region and Language settings of operating system. We would like to respect the settings in our application, i.e., we would like all mechanisms which care about the formatting of values to use CultureInfo.CurrentCulture static property-the property holds the user settings.

Step by Step to Solution

If you try to bind your View to a property (type of double) of your ViewModel, the first thing which you notice (if you are not from an English speaking country) is that Binding defaults formatting of decimal numbers to the English customs as is shown in following piece of simplified XAML code and its resulting window. Note that the window has set DataContext to double value 100.5.

<Window>
   <TextBlock Text="{Binding}"/>
?</Window>

The reason is that the Binding (its underlying converting mechanism) formats the value according to FrameworkElement.Language property. The default value of this property is “en-US”. Here comes the first possible solution into mind how to make it to format the value according to CultureInfo.CurrentCulture.

Because the value of this property is inheritable, you can set the value of the property Language on the root element (Window) to the one which you want and the right formatting will be ensured.

<Window Language="cs">
   <TextBlock Text="{Binding}"/>
?</Window>

Now you can see that the value is formatted as is usual in the Czech country. But the solution is still not perfect with respect to our expectations.

The property Language is of type of XmlLanguage. An instance of the XmlLanguage can be retrieved by a static method GetLanguage(string ietfLanguageTag). The XmlLanguage has a method GetSpecificCulture() which returns a CultureInfo which is used for the formatting but the CultureInfo is not the same as the one in CultureInfo.CurrentCulture static property. It is a standard CultureInfo which corresponds to ietfLanguageTag passed to the GetLanguage method - there aren't any user modifications of formatting.

If you set decimal places delimiter to #, you will see that it does not influence the formatted value.

The resulting window for the last XAML is still the same which is not desired.

Modification of the Language property is not simply the right way how to achieve the goal. Don’t worry. The reliable solution really exists.

Binding has a property ConverterCulture which is of type CultureInfo. The documentation for this property says:

Gets or sets the culture in which to evaluate the converter.

If you do not set this property, the binding engine uses the Language property of the binding target object. In XAML this defaults to "en-US" or inherits the value from the root element (or any element) of the page, if one has been explicitly set.

The value of this property is passed into IValueConverter as the last argument of its two methods, Convert and ConvertBack but moreover the argument is also used for formatting value into and from string. As the text from the documentation says, the ConverterCulture has a priority. So if you want to format your values exactly according to the user settings, set the ConverterCulture of your Binding to CultureInfo.CurrentCulture.

New XAML file and the resulting window will look like this one:

<Window xmlns:globalization="clr-namespace:System.Globalization;assembly=mscorlib">
   <TextBlock Text="{Binding ConverterCulture={x:Static globalization:CultureInfo.CurrentCulture}}"/>
</Window>

It is exactly what we want.

If you are too lazy (like me) to set the ConverterCulture property everywhere in your binding, you can use the following class instead of the standard Binding.

public class CustomBinding : System.Windows.Data.Binding
{
    public CustomBinding()
    {
        ConverterCulture = CultureInfo.CurrentCulture;
    }
?}

The class does only one simple thing. It sets ConverterCulture property to  CultureInfo.CurrentCulture by default. Which is exactly what we want and can be used everywhere where you use standard Binding.

Usage of the class is simple:

<Window xmlns:wpfApplication="clr-namespace:WpfApplication">
   <TextBlock Text="{wpfApplication:CustomBinding}"/>
?</Window>

That’s all. I believe that it will help you.

License

This article has no explicit license attached to it but may contain usage terms in the article text or the download files themselves. If in doubt please contact the author via the discussion board below.

A list of licenses authors might use can be found here