XAML中的文化感知货币格式化

4
我可以翻译中文。这段内容是关于在数据网格中绑定货币值并进行格式化的,相关的XAML如下:
<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>  

这是当前绑定到列中的值(该值作为数字文字来自数据库):

12345678.90

当文化设置为en-US时,此值将被输出。
12345678.90 //notice the decimal point

这是在区域设置为nl-NL时输出的值。
12345678,90 //notice the comma

你可以看到文化程度得到了一定的尊重。然而,输出结果并不是我所期望的。
对于en-US文化,我希望输出结果为$12,345,678.90。对于nl-NL文化,我希望输出结果为€ 12.345.680,00
在我的XAML代码中,我手动设置了文化(仅用于测试),使用以下代码:
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();
}

问题

为什么即使我指定了货币格式,货币符号和数字分隔符也没有显示出来呢?

手动在代码后台中进行相同数字的格式化可以给我想要的结果,但我想在XAML中完成这个操作。

我尝试过的方法 我已经尝试了以下解决方法,但都无济于事:

<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}"/>

我有没有遗漏什么?


你的代码应该可以正常工作并显示货币符号,问题可能出在其他地方。你能展示一下你绑定的类的定义吗(包含VALUATION属性的类)? - Evk
没有使用类定义进行绑定。绑定是针对由SQL查询返回的数据表进行的。数据网格的名称为dataGrid,数据以以下方式绑定:dataGrid.ItemsSource = ToDataTable(results).DefaultView;。数据绑定没有问题。 - Dodzi Dzakuma
作为一个猜测,也许您在绑定发生之前已经将数字转换为字符串,因此在那个数据表中,VALUATION 已经是 String 类型(不是 decimal\float)。 - Evk
如果是这样的话(我认为你是对的),那么推荐的行动方案是什么?我想避免需要创建一个绑定类。也希望避免代码在后台。 - Dodzi Dzakuma
1
你可以使用转换器来绑定数据,甚至可以通过这种方式检查获取的值是“string”还是“double”。顺便提一下,如果你在一个用户控件中使用它,你也需要在那里设置区域信息,XAML xml:lang="nl-NL" - XAMlMAX
@XAMlMAX,我采用了你的建议,并找到了这个网站来设置我的转换器。使用你提供的自定义转换器作为调试值的方法,让我发现它在代码执行的早期被转换为字符串。停止这个过程后,我可以使用默认的货币转换器。非常感谢你的帮助!如果你能把这个作为可能的解决方案发布出来,我会将其标记为答案。 - Dodzi Dzakuma
1个回答

3

如我们在评论中所说。
可能未显示货币符号的原因是您使用的UserControl没有使用正确的文化。当我在不包含xaml中的ResourceDictionary的情况下使用DynamicResource来为Button设置样式时,我发现了相似的行为。我的意思是,样式被部分应用,就像您的情况一样,小数点变成了逗号,但没有货币符号。
强制UserControl使用所需的文化的一种方法是在UserControl xaml文件中包含此片段:

<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>  

现在,为了制作转换器,您需要创建一个类,看起来像这样:

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();
        }
    }
}

请注意,转换器有一个cultureInfo参数,因此如果需要,您可以根据您的开发情况手动更改它。
同时,通过使用转换器,您可以通过进行简单的检查来确定传入的数据类型:
if(value is int)

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接