【问题标题】:Localize currency values in WPF GridView with different cultures for each row based on XAML bindings to culture name property基于 XAML 绑定到区域性名称属性,使用不同区域性在 WPF GridView 中本地化货币值
【发布时间】:2012-11-22 05:15:05
【问题描述】:

第一次在这里发贴,但已经阅读了很久,最后遇到了一个我无法回答的问题。

我有一个 ListView 托管一个包含多列的 GridView。一个显示价格,另一个显示货币代码(CAD、USD、GBP 等)。这一切都是使用实体框架从 SQL 服务器中提取出来的,因此 GridView 数据绑定到存储我的查询结果的 IEnumerable。货币代码存储在带有本地化字符串 (en-US, en-GB) 的单独表中,该字符串(在此应用程序的 WinForms 版本中)以前在 String.Format() 中用于本地化货币以显示适当的货币格式和符号。

我遇到的问题是在 XAML 中将 Price 绑定的 ConverterCulture 绑定到 Currency.LocalizedCultureName 以使其格式正确。这是我当前的 XAML:

            <ListView Grid.Column="0" Name="pricingListingListView" ItemsSource="{Binding Source={StaticResource pricesByYear}}">
            <ListView.GroupStyle>
                <GroupStyle>
                    <GroupStyle.ContainerStyle>
                        <Style TargetType="{x:Type GroupItem}">
                            <Setter Property="Template">
                                <Setter.Value>
                                    <ControlTemplate TargetType="{x:Type GroupItem}">
                                        <GroupBox Header="{Binding Name}" Margin="0,0,0,10">
                                            <ItemsPresenter/>
                                        </GroupBox>
                                    </ControlTemplate>
                                </Setter.Value>
                            </Setter>
                        </Style>
                    </GroupStyle.ContainerStyle>
                </GroupStyle>
            </ListView.GroupStyle>
            <ListView.View>
                <GridView>
                    <GridViewColumn HeaderContainerStyle="{StaticResource leftAlignedColumnHeader}" Header="Date" DisplayMemberBinding="{Binding Source.Date}" Width="60" />
                    <GridViewColumn HeaderContainerStyle="{StaticResource leftAlignedColumnHeader}" Header="Price" DisplayMemberBinding="{Binding Price, StringFormat='{}{0:C}', ConverterCulture={Binding Currency.LocalizedCultureName}}" Width="60" />
                    <GridViewColumn HeaderContainerStyle="{StaticResource leftAlignedColumnHeader}" Header="Currency" DisplayMemberBinding="{Binding Currency.Code}" Width="60" />
                    <GridViewColumn HeaderContainerStyle="{StaticResource leftAlignedColumnHeader}" Header="Unit" DisplayMemberBinding="{Binding Unit.Name}" Width="60" />
                    <GridViewColumn HeaderContainerStyle="{StaticResource leftAlignedColumnHeader}" Header="Source" DisplayMemberBinding="{Binding Source.Name}" Width="125" />
                    <GridViewColumn HeaderContainerStyle="{StaticResource leftAlignedColumnHeader}" Header="Project" DisplayMemberBinding="{Binding Project.Description}" Width="125" />
                    <GridViewColumn HeaderContainerStyle="{StaticResource leftAlignedColumnHeader}" Header="Plant Type" DisplayMemberBinding="{Binding Project.Plant.Name}" Width="100" />
                </GridView>
            </ListView.View>
        </ListView>

PricesByYear 只是一个 CollectionViewSource,它在我后面的代码中将 IEnumerable 从 DP 中提取出来。数据被正确拉出,只是没有格式化。

这编译得很好,但是当我加载包含它的窗口时会生成 XamlParseException:不能在“Binding”类型的“ConverterCulture”属性上设置“Binding”。只能在 DependencyObject 的 DependencyProperty 上设置“绑定”。

产生错误的行是:

简短的目标是显示价格,但根据存储为字符串值的文化名称对其进行格式化。网格视图中的每一行都可能不同。看来我无法在绑定中绑定,有没有其他方法可以解决这个问题?

回答

多重绑定成功了,这是有效的 XAML:

<local:LocalizeCurrencyMultiConverter x:Key="localizeCurrencyMultiConverter"/>

...

<GridViewColumn HeaderContainerStyle="{StaticResource leftAlignedColumnHeader}" Header="Price"  Width="60">
                        <!--DisplayMemberBinding="{Binding Price, StringFormat='{}{0:C}', ConverterCulture={Binding Currency.LocalizedCultureName}}"-->
                        <GridViewColumn.DisplayMemberBinding>
                            <MultiBinding Converter="{StaticResource localizeCurrencyMultiConverter}">
                                <Binding Path="Price"/>
                                <Binding Path="Currency.LocalizedCultureName"/>
                            </MultiBinding>
                        </GridViewColumn.DisplayMemberBinding>
                    </GridViewColumn>

还有转换器类:

    public class LocalizeCurrencyMultiConverter :System.Windows.Data.IMultiValueConverter {
    public object Convert(object[] values, Type targetType, object parameter, System.Globalization.CultureInfo culture) {
        string localizedCurrency;

        if (!values.Any() || values[0] == null)
            throw new ArgumentException("Convert requires a minimum a price to display, and optionally a culture.");

        double originalCurrency;
        if (!double.TryParse(values[0].ToString(), out originalCurrency))
            return values[0];
        string localization = (values[1] ?? "en-CA").ToString();

        try {
            localizedCurrency = string.Format(System.Globalization.CultureInfo.CreateSpecificCulture(localization), "{0:c}", originalCurrency);
        } catch {
            localizedCurrency = string.Format(System.Globalization.CultureInfo.CreateSpecificCulture("en-CA"), "{0:c}", originalCurrency);
        }
        return localizedCurrency;
    }

    public object[] ConvertBack(object value, Type[] targetTypes, object parameter, System.Globalization.CultureInfo culture) {
        throw new NotImplementedException();
        return null;
    }
}

像魅力一样工作。

【问题讨论】:

    标签: wpf gridview binding culture


    【解决方案1】:
    1. 使用与 Price 属性绑定和 Culture 属性绑定的 MultiBinding,
    2. 编写一个 MultiValueConverter 并使用这些值来输出您想要的字符串。

    我会让你轻松:

    MSDN MultiBinding

    MSDN MultiConverter

    【讨论】:

    • 感谢 Grafix - 成功了。我将在 OP 中发布工作代码。
    猜你喜欢
    • 2014-05-31
    • 1970-01-01
    • 1970-01-01
    • 2011-11-01
    • 2023-03-19
    • 1970-01-01
    • 2015-06-06
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多