如何在WPF中使用Windows的自定义区域和语言设置

Pie*_*ler 7 wpf localization currency cultureinfo

我在纳米比亚工作.纳米比亚不是Windows区域和语言设置的选项,但与南非共享大多数文化细节,因此我们选择英语南非,然后将货币符号自定义为"N $"(纳米比亚元)而不是"R"(南非兰特).

但是,我无法说服WPF使用自定义货币.string.format("{0:c}", foo)在代码中使用工作正常,但{Binding Path=SomeCurrencyValue, StringFormat=c在XAML中使用}`仍然使用"R"符号而不是自定义"N $"符号.

App.xaml.cs我使用以下代码设置应用程序文化:

System.Threading.Thread.CurrentThread.CurrentUICulture = new System.Globalization.CultureInfo(System.Globalization.CultureInfo.CurrentCulture.LCID, true);

FrameworkElement.LanguageProperty.OverrideMetadata(typeof(FrameworkElement),
                                                        new FrameworkPropertyMetadata(
                                                            System.Windows.Markup.XmlLanguage.GetLanguage(
                                                                System.Globalization.CultureInfo.CurrentUICulture.IetfLanguageTag)));
Run Code Online (Sandbox Code Playgroud)

作为演示,这里有一些显示问题的XAML代码:

<StackPanel>
    <TextBlock>
        Formatted in XAML with: <LineBreak/>
        Text="{Binding Path=SomeCurrencyValue, StringFormat=c}" <LineBreak/>
        Result:
    </TextBlock>

    <TextBox Text="{Binding Path=SomeCurrencyValue, StringFormat=c, Mode=OneWay}"
             Margin="5"/>

    <TextBlock>
        Formatted in code with: <LineBreak/>
        return string.Format("{0:c}", SomeCurrencyValue); <LineBreak/>
        Result:
    </TextBlock>

    <TextBox Text="{Binding Path=SomeCurrencyString, Mode=OneWay}"
             Margin="5"/>

</StackPanel>
Run Code Online (Sandbox Code Playgroud)

DataContext对上述观点包含以下内容:

public double SomeCurrencyValue
{
    get { return 34.95; }

}

public string SomeCurrencyString
{
    get
    {
        return string.Format("{0:c}", SomeCurrencyValue);
    }
}
Run Code Online (Sandbox Code Playgroud)

结果如下: 货币发行结果

我知道有一个类似的问题在这里,但我希望有一个更完整的问题得到更好的答案.我主要致力于为纳米比亚客户提供金融应用程序,所以这对我来说是一个非常严重的问题 - 如果用.NET 4.0无法做到这一点,我会考虑提交错误报告,但我只是想先查看一下.

编辑:

刚刚在这个问题上打开了赏金.我希望解决方案不是一个非常简单的解决方法,或者确认这是一个错误,应该这样提交.

Sim*_*ier 4

解决此问题的一种方法是创建此纳米比亚文化信息,以便所有 .NET 层完全识别它。这是执行此操作的代码:

public static void RegisterNamibianCulture()
{
    // reference the sysglobl.dll assembly for this
    CultureAndRegionInfoBuilder namibianCulture = new CultureAndRegionInfoBuilder("en-NA", CultureAndRegionModifiers.None);

    // inherit from an existing culture
    namibianCulture.LoadDataFromCultureInfo(new CultureInfo("en-za"));
    namibianCulture.CultureEnglishName = "Namibia";
    namibianCulture.RegionEnglishName = "Namibia";
    namibianCulture.CultureNativeName = "Namibia"; // you may want to change this
    namibianCulture.RegionNativeName = "Namibia"; // you may want to change this

    // see http://en.wikipedia.org/wiki/ISO_3166-1, use user-defined codes
    namibianCulture.ThreeLetterISORegionName = "xna"; // I use x as 'extended' and 'na' as namibia
    namibianCulture.TwoLetterISORegionName = "xn";
    namibianCulture.ThreeLetterWindowsRegionName = namibianCulture.ThreeLetterISORegionName;

    // see http://www.currency-iso.org/dl_iso_table_a1.xml
    namibianCulture.ISOCurrencySymbol = "nad";
    namibianCulture.CurrencyEnglishName = "Namibia Dollar";
    namibianCulture.CurrencyNativeName = "Namibia Dollar"; // you may want to change this

    // this is were you build something specific, like this symbol you need
    namibianCulture.NumberFormat.CurrencySymbol = "N$";

    // you'll need admin rights for this
    namibianCulture.Register();
}

public static void UnregisterNamibianCulture()
{
    CultureAndRegionInfoBuilder.Unregister("en-NA");
}
Run Code Online (Sandbox Code Playgroud)

在给定计算机上调用一次 Register 函数后(您需要在最终用户计算机上安装此区域性),您现在可以使用初始 WPF 启动代码,只需将其更改如下:

System.Threading.Thread.CurrentThread.CurrentUICulture = new CultureInfo("en-NA");
Run Code Online (Sandbox Code Playgroud)

一切都应该按预期进行。您还可以使用标准语言标签和所有爵士乐,因为 en-NA 现在已被识别。