我在纳米比亚工作。纳米比亚不是Windows区域和语言设置的选项,但与南非共享大多数文化细节,因此我们选择英语南非,然后自定义货币符号为“N $”(纳米比亚元) )而不是“R”(南非兰特)。
但是,我无法说服WPF使用自定义货币。在代码中使用string.format("{0:c}", foo)
工作正常,但在XAML中使用{Binding Path=SomeCurrencyValue, StringFormat=c
}`仍然使用“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)));
作为演示,这里有一些显示问题的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>
上述视图的DataContext
包含以下内容:
public double SomeCurrencyValue
{
get { return 34.95; }
}
public string SomeCurrencyString
{
get
{
return string.Format("{0:c}", SomeCurrencyValue);
}
}
结果如下:
我知道有一个类似的问题here,但我希望通过一个更完整的问题得到更好的答案。我主要致力于为纳米比亚客户提供金融应用程序,所以这对我来说是一个非常严重的问题 - 如果用.NET 4.0无法做到这一点,我会考虑提交错误报告,但我只是想先查看一下
修改
刚刚开启了这个问题的赏金。我希望解决方案不是一个非常简单的解决方法,或者确认这是一个错误,应该这样提交。
答案 0 :(得分:4)
对此的一个解决方案是创建这个纳米比亚CultureInfo,因此它被所有.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");
}
在给定计算机上调用一次Register函数(您需要在最终用户计算机上安装此文化)后,您现在可以使用初始WPF启动代码,只需更改它:
System.Threading.Thread.CurrentThread.CurrentUICulture = new CultureInfo("en-NA");
一切都应该按预期工作。您还可以使用标准语言标签和所有爵士乐,因为现在可以识别en-NA。
答案 1 :(得分:1)
我遇到了同样的问题,我从Simon的回答(谢谢你,Simon)做了一些修改,以便每次启动应用程序时获得用户配置(控制面板中的区域和语言),而不是文化默认值。
我的代码看起来像这个
public MainWindow()
{
CreateAndRegisterLocalizedCulture();
this.Language = XmlLanguage.GetLanguage(customCultureName);
InitializeComponent();
DataContext = new ViewModel();
}
private void CreateAndRegisterLocalizedCulture()
{
CultureAndRegionInfoBuilder customCulture = new CultureAndRegionInfoBuilder(customCultureName, CultureAndRegionModifiers.None);
// Inherits from the current culture and region, may be configured by the user
customCulture.LoadDataFromCultureInfo(CultureInfo.CurrentCulture);
customCulture.LoadDataFromRegionInfo(RegionInfo.CurrentRegion);
// Not needed for the culture sake but...
customCulture.CultureEnglishName = CultureInfo.CurrentCulture.EnglishName + "-Customized";
customCulture.CultureNativeName = CultureInfo.CurrentCulture.NativeName + "-Customized";
// If the custom culture is already registered an unregistration is needed
// otherwise the following Register() call will generate an exception
if (CultureInfo.GetCultures(CultureTypes.UserCustomCulture).Where(ci => (ci.Name == customCulture)).Count() != 0)
{
// Admin rights are needed here
CultureAndRegionInfoBuilder.Unregister(customCulture);
}
// Admin rights are needed here
customCulture.Register();
}
这对我很好,但这种方法有两个问题:
一些不是真正的问题但有点奇怪的是,一旦我在控制面板中更改了区域设置,我必须在看到修改之前启动我的应用程序两次。我能活下来:))