根据 CurrentCulture 进行绑定






4.73/5 (8投票s)
根据 CurrentCulture 进行绑定
引言
关于这个问题,你可以在互联网上找到很多问题。 也有很多关于这个问题的答案 - 但哪个最好呢? 如果你理解这个问题,你可以简单地选择最好的一个。 我将尝试解释它内部是如何工作的。 首先,让我们定义一下绑定和值格式化方面的问题到底是什么。
如果你假设你的应用程序将在多语言环境中被使用,你希望根据地区习俗来格式化应用程序中的值。 此外,默认的地区格式化习俗可能被运行应用程序的计算机的用户修改。
在捷克环境中,将小数格式化为以下形式是很常见的:10 000,5。在英语国家,它将是:10,000.5。 尽管如此,可能有一个用户(也许是一个捷克程序员)希望使用英语格式,因此他在操作系统的“区域和语言”设置中将小数的默认格式更改为英语格式。 我们希望在我们的应用程序中尊重这些设置,也就是说,我们希望所有关心值格式化的机制都使用 CultureInfo.CurrentCulture static
属性 - 该属性保存用户设置。
逐步解决
如果你尝试将你的 View 绑定到你的 ViewModel
的属性(double 类型),你首先注意到的是(如果你不是来自英语国家),Binding 默认将小数格式化为英语习俗,如下面的简化 XAML 代码及其结果窗口所示。 请注意,窗口已将 DataContext
设置为 double
值 100.5
。
<Window>
<TextBlock Text="{Binding}"/>
?</Window>
原因是绑定(其底层的转换机制)根据 FrameworkElement.Language
属性来格式化值。 此属性的默认值为“en-US
”。 这里是第一个可能的解决方案,即如何使其根据 CultureInfo.CurrentCulture
格式化值。
因为此属性的值是可继承的,所以你可以在根元素 (Window
) 上将 Language
属性的值设置为你想要的那个,并且将确保正确的格式化。
<Window Language="cs">
<TextBlock Text="{Binding}"/>
?</Window>
现在你可以看到,该值按照捷克国家的习惯进行格式化。 但就我们的期望而言,这个解决方案仍然不够完美。
Language
属性的类型是 XmlLanguage
。 XmlLanguage
的实例可以通过 static
方法 GetLanguage(string ietfLanguageTag)
来检索。 XmlLanguage
有一个方法 GetSpecificCulture()
,它返回一个 CultureInfo
,用于格式化,但 CultureInfo
与 CultureInfo.CurrentCulture static
属性中的不同。 这是一个标准的 CultureInfo
,它对应于传递给 GetLanguage
方法的 ietfLanguageTag
- 没有用户的格式化修改。
如果你将小数点分隔符设置为 #
,你将看到它不会影响格式化的值。
最后一个 XAML 的结果窗口仍然是一样的,这不是我们想要的。
修改 Language
属性不是实现目标的正确方法。 别担心。 真正的解决方案确实存在。
Binding 有一个 ConverterCulture
属性,它的类型是 CultureInfo
。 该属性的文档说
获取或设置用于评估转换器的文化。
…
如果你没有设置此属性,绑定引擎将使用绑定目标对象的 Language 属性。 在 XAML 中,这默认为“en-US”或从页面的根元素(或任何元素)继承该值(如果已显式设置)。
此属性的值作为其两个方法 Convert
和 ConvertBack
的最后一个参数传递给 IValueConverter
,但此外,该参数也用于将值格式化为 string
和从 string
格式化。 正如文档中的文本所说,ConverterCulture
具有优先级。 因此,如果你想完全按照用户设置格式化你的值,请将你的 Binding
的 ConverterCulture
设置为 CultureInfo.CurrentCulture
。
新的 XAML 文件和结果窗口将如下所示
<Window xmlns:globalization="clr-namespace:System.Globalization;assembly=mscorlib">
<TextBlock Text="{Binding ConverterCulture={x:Static globalization:CultureInfo.CurrentCulture}}"/>
</Window>
这正是我们想要的。
如果你太懒(像我一样)在你的绑定中到处设置 ConverterCulture
属性,你可以使用以下类代替标准 Binding。
public class CustomBinding : System.Windows.Data.Binding
{
public CustomBinding()
{
ConverterCulture = CultureInfo.CurrentCulture;
}
?}
该类只做一件简单的事情。 它默认将 ConverterCulture
属性设置为 CultureInfo.CurrentCulture
。 这正是我们想要的,并且可以在任何使用标准 Binding 的地方使用。
类的用法很简单
<Window xmlns:wpfApplication="clr-namespace:WpfApplication">
<TextBlock Text="{wpfApplication:CustomBinding}"/>
?</Window>
就这样。 我相信它会对你有所帮助。