Use CultureInfo.CurrentCulture “real” na binding WPF, não CultureInfo de IetfLanguageTag

No meu caso:

Eu tenho um TextBlock Binding para uma propriedade do tipo DateTime. Eu quero que seja exibido como as configurações regionais do usuário diz.

 

Eu estou definindo a propriedade de linguagem como WPF XAML Bindings e CurrentCulture Display diz:

 this.Language = XmlLanguage.GetLanguage(CultureInfo.CurrentCulture.IetfLanguageTag); 

Mas com esta linha de código, ele apenas exibe o texto como o formato padrão de CultureInfo com o IetfLanguageTag de CurrentCulture, não como o valor efetivo selecionado nas configurações da região de sistemas diz:

(por exemplo, para “de-DE” dd.MM.yyyy é usado em vez de yyyy-MM-dd selecionado)

Configurações de região: não o padrão, mas o yyy-MM-dd é usado

Existe uma maneira de vinculação usa o formato correto sem definir ConverterCulture em cada binding única?

Em código

 string.Format("{0:d}",Date); 

usa as configurações de cultura certas.

editar:

outra maneira que não funciona como desejado (como this.Language = … does):

 xmlns:glob="clr-namespace:System.Globalization;assembly=mscorlib" 

e

  

Você pode criar uma subclass de binding (por exemplo, CultureAwareBinding), que define o ConverterCulture automaticamente para a cultura atual quando criada.

Não é uma solução perfeita, mas é provavelmente a única, já que forçar retroativamente a Binding a respeitar a cultura poderia quebrar outro código no WPF que depende desse comportamento.

Deixe-me saber se você precisar de mais ajuda!

Esta é uma extensão da resposta do KzenT. Eles propuseram que deveríamos criar uma subclass da class Binding e definir o ConverterCulture como CurrentCulture. Mesmo que a resposta seja muito direta, eu sinto que algumas pessoas podem não estar muito confortáveis ​​em implementá-la, então estou compartilhando a versão do código da resposta do aKzenT com um exemplo de como usá-la no XAML.

 using System; using System.Globalization; using System.Windows.Data; namespace MyWpfLibrary { public class CultureAwareBinding : Binding { public CultureAwareBinding() { ConverterCulture = CultureInfo.CurrentCulture; } } } 

Exemplo de como usar isso no XAML

1) Você precisa importar seu namespace em seu arquivo XAML:

  

2) Uso no mundo real do CultureAwareBinding

  

Coloque a linha de código a seguir, antes de qualquer UI ser inicializada. Isso funcionou para mim.

 FrameworkElement.LanguageProperty.OverrideMetadata(typeof(FrameworkElement), new FrameworkPropertyMetadata(XmlLanguage.GetLanguage(CultureInfo.CurrentCulture.IetfLanguageTag))); 

(E remova todos os parâmetros de cultura explícitos)

Sua segunda tentativa foi próxima e me levou a uma solução que funciona para mim.

O problema com a configuração do ConverterCulture é que ele é usado somente quando você tem um conversor. Então, basta criar um StringFormatConverter simples que use o formato como parâmetro:

 public sealed class StringFormatConverter : IValueConverter { private static readonly StringFormatConverter instance = new StringFormatConverter(); public static StringFormatConverter Instance { get { return instance; } } private StringFormatConverter() { } public object Convert(object value, Type targetType, object parameter, CultureInfo culture) { return string.Format(culture, (string)parameter, value); } public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture) { throw new NotSupportedException(); } } 

Então você pode ajustar sua binding (supondo que você tenha importado o namespace do conversor como “meu”)

  

Eu criei um truque / solução que evita atualizar todas as suas ligações. Adicione este código ao construtor da sua janela principal.

 XmlLanguage language = XmlLanguage.GetLanguage("My-Language"); typeof(XmlLanguage).GetField("_compatibleCulture", BindingFlags.Instance | BindingFlags.NonPublic).SetValue(language, CultureInfo.CurrentCulture); this.Language = language; 

Como está a usar a reflection, não há garantia de que funcionará no futuro, mas por enquanto acontece (.NET 4.6).

Eu uso esse código com resultados adequados às minhas necessidades. Espero que possa preencher o seu :-)! Talvez você seja melhor jogando uma exceção se não puder “TryParse”. Você decide.

 public sealed class CurrentCultureDoubleConverter : IValueConverter { public object Convert(object value, Type targetType, object parameter, CultureInfo culture) { return ((double)value).ToString((string)parameter ?? "0.######", CultureInfo.CurrentCulture); } public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture) { double result; if (Double.TryParse(value as string, NumberStyles.Number, CultureInfo.CurrentCulture, out result)) { return result; } throw new FormatException("Unable to convert value:" + value); // return value; } } 

Uso:

            

Que tal mudar a lanaguge no código por trás?

 this.Language = XmlLanguage.GetLanguage(Thread.CurrentThread.CurrentCulture.Name); 

O problema que está evitando usar “this.Language = XmlLanguage.GetLanguage (Thread.CurrentThread.CurrentCulture.Name);” não é realmente comum. Eu não conheço nenhum usuário aqui na frança que irá mudar o formato de data para EUA ou Japão, só porque pelo menos nenhum usuário está sabendo que tal mudança é possível (e não sei como fazer isso) … Então de Claro que a “linguagem =” não é perfeita, mas em muitos anos de prática no WPF e no Silverlight eu nunca vejo um problema desse tipo com qualquer usuário … Então eu ainda uso o truque “Langage =”, é simples e cobre 100% das necessidades reais. É claro que outras soluções parecem ser melhores, mas não há necessidade (e eu vi algumas implementações que estão longe de serem comparadas com a solução “language =”).