2009-02-06 10 views
96

en WPF 3.5SP1 yo uso el último StringFormat función en DataBindings:cuestiones StringFormat localización en WPF

<TextBlock Text="{Binding Path=Model.SelectedNoteBook.OriginalDate, StringFormat='f'}" 
            FontSize="20" 
            TextTrimming="CharacterEllipsis" /> 

El problema que enfrentamos es que la fecha siempre está formateado en Inglés ... aunque mi sistema está en Francés ? ¿Cómo puedo forzar la fecha para seguir la fecha del sistema?

+10

3 años ¡Una pregunta mejor evaluada pero no tiene respuestas! Caras tristes todo el año. – Gusdor

Respuesta

181
// Ensure the current culture passed into bindings is the OS culture. 
// By default, WPF uses en-US as the culture, regardless of the system settings. 
FrameworkElement.LanguageProperty.OverrideMetadata(
     typeof(FrameworkElement), 
     new FrameworkPropertyMetadata(
      XmlLanguage.GetLanguage(CultureInfo.CurrentCulture.IetfLanguageTag))); 

De Creating an Internationalized Wizard in WPF

+14

Sí, esto es bastante molesto. +1 –

+2

Gracias por resolver mi dolor de cabeza. – Skurmedel

+4

¿Qué hay de Silverlight? No tiene el método OverrideMetadata ... – andrecarlucci

-3

uso de etiquetas (incluyendo Cultture) y no texblock

+1

Lea la pregunta y la respuesta, no por su cuenta. – Mohanavel

8

Si necesita cambiar el idioma mientras se ejecuta el programa sólo puede cambiar la propiedad de idioma en el elemento raíz (im no está seguro si esto tiene un efecto inmediato o si el elemento secundario tiene que ser recreada, en mi caso esto funciona al menos)

element.Language = System.Windows.Markup.XmlLanguage.GetLanguage(culture.IetfLanguageTag); 
+0

reevalúa inmediatamente pero lamentablemente tiene que configurarse para cada rootelement (ventana) separado – Firo

73

Definir el followin g xml espacio de nombres:

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

Y he aquí este fantástico arreglo:

<TextBlock Text="{Binding Path=Model.SelectedNoteBook.OriginalDate, StringFormat='f', ConverterCulture={x:Static gl:CultureInfo.CurrentCulture}" FontSize="20"TextTrimming="CharacterEllipsis" /> 

Soy muy consciente de que esto no es una solución global y que se requieren en cada uno de sus enlaces, pero sin duda que es solo bueno XAML? Por lo que sé, la próxima vez que las actualizaciones de enlace utilizará el CultureInfo.CurrentCulture correcto o lo que haya proporcionado.

This solution will immediately update your Bindings with the correct values pero parece mucho código para algo tan raro e inocuo.

+3

¡Excelente! ¡Esto funcionó maravillosamente! No tengo problemas añadiendo esto a los pocos lugares donde es necesario. Por cierto tu ejemplo falta un} – Johncl

+0

Genial, lo que estoy buscando .. – Mohanavel

+0

Respuesta perfecta. – Karthik

9

basta con insertar el acceso directo de la cultura a la etiqueta de nivel superior:

xml:lang="de-DE" 

ej .:

<Window x:Class="MyApp" 
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" 
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" 
    xml:lang="de-DE" 
    Title="MyApp" Height="309" Width="497" Loaded="Window_Loaded">....</Window> 
+4

Pero esto es tan malo como suponer que en-US es la cultura 'correcta'. Debería tomar la configuración de la máquina del usuario. – misnomer

+0

¡Muchas gracias, esto era exactamente lo que estaba buscando! Si WPF cree que en-EN es la cultura correcta para cualquier situación, también puedo hacerlo con mi propia localización. Como estoy trabajando en una aplicación de prueba de concepto donde la velocidad de desarrollo está a la orden del día, no hay tiempo para meterse con docenas de líneas de código solo para obtener un solo 'DatePicker' para hacer su trabajo, por lo que una solución fácil me ayudó a recuperarme rápidamente! – M463

+0

mejor respuesta para mi caso, finalmente he estado buscando edades :) y por supuesto es correcto, o asumes que es en-US o es de-DE ... la gente siempre tiene problemas con soluciones simples -.- – MushyPeas

5

Sólo quería añadir que loraderon 's respuesta funciona muy bien en la mayoría de los casos. Cuando coloco la siguiente línea de código en mi App.xaml.cs, las fechas en mis TextBlocks están formateadas en la cultura correcta.

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

digo 'más cases'.For ejemplo, esto va a funcionar fuera de la caja:

<TextBlock Text="{Binding Path=Date, StringFormat={}{0:d MMMM yyyy}}" /> 
--> "16 mei 2013" (this is in Dutch) 

... pero cuando se utiliza en una fuga de TextBlock, el DateTime tienen el formato por defecto cultura.

<TextBlock> 
    <Run Text="Datum: " /> 
    <Run Text="{Binding Path=Date, StringFormat={}{0:d MMMM yyyy}, Mode=OneWay}" /> 
</TextBlock> 
--> "Datum: 16 may 2013" (this is in English, notice the 
    name of the month "may" vs. "mei") 

Para que esto funcione, que necesitaba respuesta Gusdor 's, es decir, añadiendo ConverterCulture = {x: gl estática: CultureInfo.CurrentCulture} para la unión.

<TextBlock> 
    <Run Text="Datum: " /> 
    <Run Text="{Binding Path=Date, StringFormat={}{0:d MMMM yyyy}, ConverterCulture={x:Static gl:CultureInfo.CurrentCulture}, Mode=OneWay}" /> 
</TextBlock> 
--> "Datum: 16 mei 2013" (=Dutch) 

Espero que esta respuesta adicional sea útil para alguien.

+0

De hecho, Run hace no deriva de FrameworkElement. Puede intentar modificar la respuesta de loraderon para repetir su código para la base de Ejecutar (FrameworkContentElement), así como para FrameworkElement. –

+0

Para aquellos que podrían preguntarse: xmlns: gl = "clr-namespace: System.Globalization; assembly = mscorlib" –

0

Si desea cambiar información cultural en tiempo de ejecución, se puede utilizar un comportamiento (véase más adelante)

public class CultureBehavior<TControl> : Behavior<TControl> 
    where TControl : FrameworkElement 
{ 
    private readonly IEventAggregator _eventAggregator; 
    private readonly Action<CultureInfo> _handler; 

    public CultureBehavior() 
    { 
     _handler = (ci) => this.AssociatedObject.Language = XmlLanguage.GetLanguage(ci.IetfLanguageTag); 
     _eventAggregator = IoC.Container.Resolve<IEventAggregator>(); 
    } 

    protected override void OnAttached() 
    { 
     base.OnAttached(); 

     _eventAggregator 
      .GetEvent<LanguageChangedEvent>() 
      .Subscribe(_handler); 

     _handler.Invoke(CultureInfo.CurrentCulture); 
    } 

    protected override void OnDetaching() 
    { 
     _eventAggregator 
      .GetEvent<LanguageChangedEvent>() 
      .Unsubscribe(_handler); 

     base.OnDetaching(); 
    } 
} 
4

El código completo para cambiar la localización también en elementos como <Run /> es la siguiente:

Private Shared Sub SetXamlBindingLanguage() 

    '' For correct regional settings in WPF (e.g. system decimal/dot or comma) 
    Dim lang = System.Windows.Markup.XmlLanguage.GetLanguage(CultureInfo.CurrentCulture.IetfLanguageTag) 
    FrameworkContentElement.LanguageProperty.OverrideMetadata(GetType(TextElement), New FrameworkPropertyMetadata(lang)) 
    FrameworkContentElement.LanguageProperty.OverrideMetadata(GetType(DefinitionBase), New FrameworkPropertyMetadata(lang)) 
    FrameworkContentElement.LanguageProperty.OverrideMetadata(GetType(FixedDocument), New FrameworkPropertyMetadata(lang)) 
    FrameworkContentElement.LanguageProperty.OverrideMetadata(GetType(FixedDocumentSequence), New FrameworkPropertyMetadata(lang)) 
    FrameworkContentElement.LanguageProperty.OverrideMetadata(GetType(FlowDocument), New FrameworkPropertyMetadata(lang)) 
    FrameworkContentElement.LanguageProperty.OverrideMetadata(GetType(TableColumn), New FrameworkPropertyMetadata(lang)) 
    FrameworkElement.LanguageProperty.OverrideMetadata(GetType(FrameworkElement), New FrameworkPropertyMetadata(lang)) 

End Sub 
5

Como ya se ha dicho, incumplimientos XAML a la referencia cultural invariable (en-US), y se puede utilizar

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

para establecer la cultura en la cultura predeterminada para el idioma de la cultura actual. Pero el comentario es incorrecto; esto hace no utilice la cultura actual, ya que no verá ninguna personalización que el usuario haya realizado, siempre será la predeterminada para el idioma.

utilizar realmente la cultura actual con las personalizaciones, tendrá que ajustar la ConverterCulture junto con el StringFormat, como en

Text="{Binding Day, StringFormat='d', ConverterCulture={x:Static gl:CultureInfo.CurrentCulture}}" 

con el gl define como un espacio de nombres global en su elemento raíz

xmlns:gl="clr-namespace:System.Globalization;assembly=mscorlib" 
+0

Si está haciendo esto a través del código en lugar de XAML, es el siguiente: 'binding.ConverterCulture = System.Globalization.CultureInfo .CurrentCulture; ' – Metalogic

0

Si está trabajando en código en lugar de XAML, puede configurar el ConverterCulture de la siguiente manera:

binding.ConverterCulture = System.Globalization.CultureInfo.CurrentCulture; 

Felicitaciones a @KZeise por señalar la sutil diferencia entre usar la definición de cultura predeterminada y usar la definición de cultura personalizada del usuario.