Dodzi Dzakuma
Dodzi Dzakuma

Reputation: 1426

Culture Aware Currency Formatting in XAML

I would like to format a currency value being bound to a a cell/column in a data grid.

The relevant XAML is as follows:

<telerik:RadGridView Grid.Row="0" Grid.ColumnSpan="2" x:Name="dataGrid" 
    AutoGenerateColumns="False" HorizontalAlignment="Stretch" 
    VerticalAlignment="Top" Margin="0,25,0,0" IsSearchingDeferred="True" 
    IsReadOnly="True" IsLocalizationLanguageRespected="False">
    <telerik:RadGridView.Columns>
        <telerik:GridViewDataColumn DataMemberBinding="{Binding Path=VALUATION, StringFormat=C}" 
            Header="{x:Static properties:Resources.AddressLine3}"/>
    </telerik:RadGridView.Columns>
</telerik:RadGridView>  

This is the value that is currently being bound to the column (the value is coming from a database as number literal):

12345678.90

This is the value that is output when the culture is set to en-US

12345678.90 //notice the decimal point

This is the value that is output when the culture is set to nl-NL

12345678,90 //notice the comma

You can see that the culture is being respected to some extent. However, the output isn't what I would expect.

For the en-US culture I would like the output to be $12,345,678.90. For the nl-NL culture I would like the output to be € 12.345.680,00.

In my XAML code behind of have manually set the culture (for testing purposes) using the following code:

public MainWindow()
{
    //I am toggling between the following cultures
    CultureInfo ci = new CultureInfo("nl-NL");
    //CultureInfo ci = new CultureInfo("ja-JP");
    //CultureInfo ci = new CultureInfo("en-US");

    //I am forcing the UI to use the culture I specify
    Thread.CurrentThread.CurrentCulture = ci;
    Thread.CurrentThread.CurrentUICulture = ci;
    this.Language = XmlLanguage.GetLanguage(ci.Name);
    Properties.Resources.Culture = ci;

    //these are used to test that to string formatting works as expected
    //when using the debugger
    float price = 12345678.90F;
    string currencyToDisplay = price.ToString("C");

    InitializeComponent();
}

Question

Why isn't the format showing currency symbols and number delimiters even though I have specified the format as currency?

Manually, formatting the same number in code behind gives me the results that I would like, but I would like to do this in XAML.

What I have tried I have tried the following workarounds to no avail:

<telerik:GridViewDataColumn DataMemberBinding="{Binding Path=VALUATION, StringFormat=C}" Header="{x:Static properties:Resources.AddressLine3}"/>
<telerik:GridViewDataColumn DataMemberBinding="{Binding Path=VALUATION, StringFormat={}{0:C}}" Header="{x:Static properties:Resources.AddressLine3}"/>
<telerik:GridViewDataColumn DataMemberBinding="{Binding Path=VALUATION, StringFormat=\{0:C\}}" Header="{x:Static properties:Resources.AddressLine3}"/>
<telerik:GridViewDataColumn DataMemberBinding="{Binding Path=VALUATION, StringFormat='C'}" Header="{x:Static properties:Resources.AddressLine3}"/>
<telerik:GridViewDataColumn DataMemberBinding="{Binding Path=VALUATION, StringFormat=c}" Header="{x:Static properties:Resources.AddressLine3}"/>
<telerik:GridViewDataColumn DataMemberBinding="{Binding VALUATION}" DataFormatString="{}{0:C}" Header="{x:Static properties:Resources.AddressLine3}"/>

Is there anything that I am missing?

Upvotes: 4

Views: 1681

Answers (1)

XAMlMAX
XAMlMAX

Reputation: 2363

As we spoke in the comments.
Possible reason for not showing the currency sign is that the UserControl that you were using wasn't using correct culture. I have found similar behavior when I used DynamicResource to style a Button without including the ResourceDictionary in the xaml. What I mean is that style was applied partially, like in your case when dot became comma but without currency sign.
One way to force the UserCpntrol to use the desired culture is to include this snippet in your UserControl xaml file:

<UserControl x:Class="WpfApplication1.Views.CultureExplicitUC"
             xml:lang="en-GB"<!--This is what you want in your UC-->
             xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
             xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
             xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" 
             xmlns:d="http://schemas.microsoft.com/expression/blend/2008" 
             xmlns:local="clr-namespace:WpfApplication1.Views"
             mc:Ignorable="d" 
             d:DesignHeight="300" d:DesignWidth="300">
    <Grid>

    </Grid>
</UserControl>  

Now for the converter you need to create class that looks like this:

namespace WpfApplication1.Converters
{
    public class DebugConverter : IValueConverter
    {
        public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
        {
            //manipulate your data here
        }

        public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
        {
            throw new NotImplementedException();
        }
    }
}

Please note that the converter has a cultureInfo as a parameter so if needed you can manually change it depending on the circumstances of your development.
Also by using converter you can determine what type of data is being passed into by doing a simple check like:
if(value is int)

Upvotes: 3

Related Questions