在WPF Binding中使用"真正的"CultureInfo.CurrentCulture,而不是来自IetfLanguageTag的CultureInfo

Mar*_*s k 37 c# wpf binding currentculture

就我而言:

我有一个TextBlock绑定到DateTime类型的属性.我希望它显示为用户的区域设置.

<TextBlock Text="{Binding Date, StringFormat={}{0:d}}" />
Run Code Online (Sandbox Code Playgroud)

我将语言属性设置为WPF XAML Bindings和CurrentCulture Display 说:

this.Language = XmlLanguage.GetLanguage(CultureInfo.CurrentCulture.IetfLanguageTag);
Run Code Online (Sandbox Code Playgroud)

但是使用这行代码,它只是将文本显示为CultureInfo的默认格式,并使用CurrentCulture的IetfLanguageTag表示,而不是在系统区域设置中选择的有效值表示:

(例如,对于"de-DE" dd.MM.yyyy用于代替选定的yyyy-MM-dd)

区域设置:不是默认设置,而是使用yyy-MM-dd

有没有一种方法Binding使用正确的格式而不在每个Binding上定义ConverterCulture?

在代码中

string.Format("{0:d}",Date);
Run Code Online (Sandbox Code Playgroud)

使用正确的文化设置.

编辑:

另一种不能按预期工作的方式(比如this.Language = ......):

xmlns:glob="clr-namespace:System.Globalization;assembly=mscorlib"
Run Code Online (Sandbox Code Playgroud)

<Binding Source="{x:Static glob:CultureInfo.CurrentCulture}" 
 Path="IetfLanguageTag" 
 ConverterCulture="{x:Static glob:CultureInfo.InvariantCulture}" />
Run Code Online (Sandbox Code Playgroud)

aKz*_*enT 27

您可以创建一个绑定子类(例如CultureAwareBinding),它在创建时自动将ConverterCulture设置为当前文化.

它不是一个完美的解决方案,但它可能是唯一的解决方案,因为追溯强制Binding以尊重文化可能会破坏WPF中依赖于此行为的其他代码.

如果您需要更多帮助,请告诉我们!

  • “因为追溯性地强制 Binding 尊重文化可能会破坏 WPF 中依赖于这种行为的其他代码。” - 我认为,从长远来看,继续保持这样的破坏行为比引入短期休息更糟糕。或者他们可以修复它,但使用 .NET 的程序集绑定功能来检测应用程序何时需要旧版本并为它们维护损坏的行为。这个错误已经在 WPF 中存在 12 年了,而且他们没有自己的内置“CultureAwareBinding”,这真是太疯狂了。 (4认同)

Par*_*hah 18

这是来自aKzenT的答案的延伸.他们建议我们应该创建一个Binding类的子类,并将ConverterCulture设置为CurrentCulture.虽然答案非常简单,但我觉得有些人可能不太习惯实现它,所以我正在分享aKzenT答案的代码版本,并举例说明如何在XAML中使用它.

using System;
using System.Globalization;
using System.Windows.Data;

namespace MyWpfLibrary
{
    public class CultureAwareBinding : Binding
    {
        public CultureAwareBinding()
        {
            ConverterCulture = CultureInfo.CurrentCulture;
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

如何在XAML中使用它的示例

1)您需要将名称空间导入XAML文件:

<Page
    ...
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:myWpfLib="clr-namespace:MyWpfLibrary;assembly=<assembly_name>"
    ...
>
Run Code Online (Sandbox Code Playgroud)

2)CultureAwareBinding的真实世界用法

<Textblock Text="{myWpfLib:CultureAwareBinding Path=Salary, Source=Contact, StringFormat={}{0:C}}" />
Run Code Online (Sandbox Code Playgroud)

  • @ Poken1151您还可以为CultureAwareBinding定义一个额外的构造函数,它将一个字符串作为唯一参数:`public CultureAwareBinding(string path):base(path){ConverterCulture = CultureInfo.CurrentCulture; }`.这样您就不需要指定`Path = ...`. (3认同)
  • 我喜欢你对此的详细解释。关于纠正某些绑定错误的任何输入吗?结果是,“类型“ CultureAwareBinding”不包含具有指定数量的参数的构造函数。“ (2认同)
  • 谢谢,我修复了错误。显然是不好的编码,{Binding ITEM-NAME ....}不好,我需要{Binding Path = ITEM-NAME,...}。那解决了我的错误(在两种情况下仍然可以编译) (2认同)

小智 6

在初始化任何UI之前,请输入以下代码行.这对我有用.

FrameworkElement.LanguageProperty.OverrideMetadata(typeof(FrameworkElement),
    new FrameworkPropertyMetadata(XmlLanguage.GetLanguage(CultureInfo.CurrentCulture.IetfLanguageTag)));
Run Code Online (Sandbox Code Playgroud)

(并删除所有显式文化参数)

  • 正如问题中所述,设置语言只会导致 WPF 使用该语言的默认日期/时间格式,而不是在系统区域设置中选择的格式。 (4认同)
  • 像魅力一样工作,只需一行代码,无需触及任何其他代码。我不明白,为什么这不是公认的答案,为什么它的赞成票如此之少。有什么陷阱吗? (2认同)