2009-06-30 3 views
53

J'ai des problèmes avec la sortie d'une valeur DateTime. La culture actuelle de mon ordinateur est définie sur De-AT (Autriche).WPF XAML StringFormat DateTime: Sortie dans une culture incorrecte?

Le code suivant

string s1 = DateTime.Now.ToString("d"); 
string s2 = string.Format("{0:d}", DateTime.Now); 

résultats dans s1 et s2 les deux ayant la valeur correcte de "30/06/2009".

Mais lorsque vous utilisez le même format XAML

<TextBlock Text="{Binding Source={x:Static sys:DateTime.Now}, StringFormat=d}"/> 

la sortie est ` "6/30/2009". Il semble que XAML StringFormat ignore les paramètres de culture actuels. Cela se produit à la fois sur Vista et XP.

Je ne souhaite pas spécifier un format personnalisé, car la sortie doit être formatée dans le paramètre de culture préféré de l'utilisateur.

Quelqu'un avec le même problème? Est-ce un bug dans WPF?

+0

J'ai juré toute la journée, j'ai trouvé ce problème à la dernière minute! – GorillaApe

+1

Il est considéré comme "par conception". Voir https://connect.microsoft.com/VisualStudio/feedback/details/442569/wpf-binding-uses-the-wrong-currentculture-by-default –

+0

vient de voir le même comportement sur Windows Phone 7. Salutations de l'Autriche! – hfrmobile

Répondre

1

vous pouvez utiliser un IValueConverter (qui prend un paramètre de culture) et mettre en forme la valeur que vous le souhaitez, quelque chose que je veux est ce convertisseur annulable par Matt Hamilton

class NullableDateTimeConverter : ValidationRule, IValueConverter 
{ 
public override ValidationResult Validate(object value, CultureInfo cultureInfo) 
{ 
    if (value == null || value.ToString().Trim().Length == 0) return null; 

    return new ValidationResult( 
     ConvertBack(value, typeof(DateTime?), null, cultureInfo) != DependencyProperty.UnsetValue, 
     "Please enter a valid date, or leave this value blank"); 
} 

#region IValueConverter Members 
public object Convert(object value, Type targetType, object parameter, CultureInfo culture) 
{ 
    if (value == null) return ""; 
    DateTime? dt = value as DateTime?; 
    if (dt.HasValue) 
    { 
     return parameter == null ? dt.Value.ToString() : dt.Value.ToString(parameter.ToString()); 
    } 
    return ""; 
} 

public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture) 
{ 
    if (value == null || value.ToString().Trim().Length == 0) return null; 
    string s = value.ToString(); 

    if (s.CompareTo("today") == 0) return DateTime.Today; 
    if (s.CompareTo("now") == 0) return DateTime.Now; 
    if (s.CompareTo("yesterday") == 0) return DateTime.Today.AddDays(-1); 
    if (s.CompareTo("tomorrow") == 0) return DateTime.Today.AddDays(1); 

    DateTime dt; 
    if (DateTime.TryParse(value.ToString(), out dt)) return dt; 

    return DependencyProperty.UnsetValue; 
} 
#endregion 

}

Heres le original

12

Pour appliquer la solution mentionnée à http://tinyurl.com/b2jegna, procédez comme suit:

(1) Ajouter un début up gestionnaire d'événements à la classe d'application dans app.xaml:

<Application x:Class="MyApp" 
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" 
    ... 
    Startup="ApplicationStartup"> 

(2) Ajouter la fonction de gestionnaire:

private void ApplicationStartup(object sender, StartupEventArgs e) 
{ 
    FrameworkElement.LanguageProperty.OverrideMetadata(
     typeof(FrameworkElement), 
     new FrameworkPropertyMetadata(XmlLanguage.GetLanguage(CultureInfo.CurrentCulture.IetfLanguageTag))); 
} 

cordes WPF doivent alors être correctement mis en forme selon la culture.

3

Si vous voulez une langue particulière, vous pouvez la définir sur l'élément de niveau supérieur en utilisant xml:lang.

Par exemple:

<Window xml:lang="de-AT"> 
... 
</Window> 
3

Je sais que cela est une question de vieillissement, mais cela a toujours travaillé pour moi et le partage des connaissances est une bonne chose. Depuis mes applications changent toujours la langue à la volée, le FrameworkElement.LanguageProperty.OverrideMetadata ne fonctionne qu'une fois et son pas bon pour moi, alors voici:

this.Language = System.Windows.Markup.XmlLanguage.GetLanguage(ActiveLanguage.CultureInfo.IetfLanguageTag); 

où (ce) est le MainWindow, en fait, vous devez le faire dans tous les rootelements (Windows). Là, vous allez assez simple.