c# wpf binding currentculture

c# - Use "real" CultureInfo.CurrentCulture en WPF Binding, no CultureInfo desde IetfLanguageTag



(8)

¿Qué hay de cambiar la lanaguge en el código detrás?

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

En mi caso:

Tengo una vinculación TextBlock a una propiedad de tipo DateTime. Quiero que se muestre como dice la configuración regional del usuario.

<TextBlock Text="{Binding Date, StringFormat={}{0:d}}" />

Estoy configurando la propiedad del idioma como WPF XAML Bindings y CurrentCulture Display dice:

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

Pero con esta línea de código solo se muestra el texto como el formato predeterminado de CultureInfo con IetfLanguageTag of CurrentCulture dice, no como dice el valor efectivo seleccionado en la configuración regional del sistema:

(por ejemplo, para "de-DE" dd.MM.aaaa se usa en lugar de aaaa-MM-dd seleccionado )

¿Existe algún modo de que Binding utilice el formato correcto sin definir ConverterCulture en cada enlace único?

En codigo

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

usa la configuración correcta de Cultura.

editar:

otra manera que no funciona como se desea (como this.Language = ... does):

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

y

<Binding Source="{x:Static glob:CultureInfo.CurrentCulture}" Path="IetfLanguageTag" ConverterCulture="{x:Static glob:CultureInfo.InvariantCulture}" />


Coloque la siguiente línea de código antes de inicializar cualquier IU. Esto funcionó para mí.

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

(Y elimine todos los parámetros de cultivo explícitos)


El problema es evitar usar "this.Language = XmlLanguage.GetLanguage (Thread.CurrentThread.CurrentCulture.Name);" no es realmente común. No conozco ningún usuario aquí en Francia que cambie el formato de fecha a uno de EE. UU. O Japón, solo porque al menos ningún usuario sabe que tal cambio es posible (y no sabe cómo hacerlo) ... Así que de Por supuesto, el "idioma =" no es perfecto, pero en muchos años de la práctica de WPF y Silverlight nunca veo un problema de este tipo con ningún usuario ... Así que todavía uso el truco "Langage =", es simple y cubre 100% de las necesidades reales. Por supuesto, otras soluciones parecen ser mejores, pero no es necesario (y vi algunas implementaciones que están lejos de ser perfectas en comparación con la solución "language =").


Encontré un truco / solución alternativa que evita la actualización de todos tus enlaces. Agregue este código al constructor de su ventana principal.

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

Como está utilizando la reflexión, no hay garantía de que funcione en el futuro, pero por ahora lo hace (.NET 4.6).


Esta es una extensión de la respuesta de aKzenT. Propusieron que creáramos una subclase de clase de vinculación y configuramos la ConversiónDeCultura en laCultura Actual. A pesar de que la respuesta es muy directa, creo que algunas personas pueden no sentirse cómodas al implementarla, por lo que estoy compartiendo la versión del código de la respuesta de aKzenT con un ejemplo de cómo usarlo en XAML.

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

Ejemplo de cómo usar esto en XAML

1) Debe importar su espacio de nombres en su archivo XAML:

<Page ... xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:myWpfLib="clr-namespace:MyWpfLibrary;assembly=<assembly_name>" ... >

2) Uso del mundo real del CultureAwareBinding

<Textblock Text="{myWpfLib:CultureAwareBinding Path=Salary, Source=Contact, StringFormat={}{0:C}}" />


Puede crear una subclase de enlace (por ejemplo, CultureAwareBinding) que establece el ConverterCulture automáticamente a la cultura actual cuando se crea.

No es una solución perfecta, pero probablemente sea la única, ya que obligando retroactivamente a Binding a respetar la cultura podría romper otro código en WPF que depende de este comportamiento.

¡Dejame saber si necesitas mas ayuda!


Tu segundo intento estuvo cerca y me llevó a una solución que funciona para mí.

El problema al configurar ConverterCulture es que solo se usa cuando tienes un convertidor. Así que simplemente cree un StringFormatConverter simple que tome el formato como su 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(); } }

Luego puedes ajustar tu enlace (asumiendo que has importado el espacio de nombres del convertidor como "mi")

<TextBlock Text="{Binding Date, Converter={x:Static my:StringFormatConverter.Instance}, ConverterCulture={x:Static glob:CultureInfo.CurrentCulture}, ConverterParameter={}{0:d}}" />


Utilizo ese código con los resultados adecuados a mis necesidades. Espero que pueda llenar tu :-)! Tal vez sea mejor lanzar una excepción si no puede "TryParse". Depende de usted.

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:

<Window xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:simulatorUi="clr-namespace:SimulatorUi" xmlns:Converter="clr-namespace:HQ.Wpf.Util.Converter;assembly=WpfUtil" x:Class="SimulatorUi.DlgTest" Title="DlgTest" Height="300" Width="300"> <Window.DataContext> <simulatorUi:DlgTestModel/> </Window.DataContext> <Window.Resources> <Converter:CurrentCultureDoubleConverter x:Key="CurrentCultureDoubleConverter"/> </Window.Resources> <Grid> <TextBox Text="{Binding DoubleVal, Converter={StaticResource CurrentCultureDoubleConverter}}"/> </Grid> </Window>