2009-06-30 21 views
53

Ich habe Probleme mit der Ausgabe eines DateTime-Wertes. Die aktuelle Kultur meines Computers ist auf de-AT (Österreich) eingestellt.WPF XAML StringFormat DateTime: Ausgabe in falscher Kultur?

den folgenden Code

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

Ergebnisse in s1 und s2 sowohl den korrekten Wert von "30.06.2009" aufweist.

Aber wenn das gleiche Format in XAML

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

der Ausgang ` "2009.06.30". Es scheint, dass das XAML StringFormat die aktuellen Kultureinstellungen ignoriert. Dies geschieht sowohl unter Vista als auch unter XP.

Ich möchte kein benutzerdefiniertes Format angeben, da die Ausgabe in der bevorzugten Kultureinstellung des Benutzers formatiert werden soll.

Jeder mit dem gleichen Problem? Ist das ein Fehler in WPF?

+0

Ich schwor den ganzen Tag, ich fand dieses Problem in letzter Minute! – GorillaApe

+1

Es gilt als "von Design". Siehe https://connect.microsoft.com/VisualStudio/feedback/details/442569/wpf-binding-uses-the-wrong-current-culture-by-default –

+0

sah das gleiche Verhalten auf Windows Phone 7. Grüße aus Österreich! – hfrmobile

Antwort

1

Sie IValueConverter nutzen könnten (die in einem Kultur Parameter übernimmt) und den Wert zu formatieren, wie Sie wollen, etwas Ich mag ist dieser Nullable-Konverter von 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 

}

heren die original

12

die Lösung bei http://tinyurl.com/b2jegna tun die folgenden erwähnt anwenden:

(1) hinzufügen Anfang Event-Handler in die Anwendungsklasse in app.xaml up:

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

(2) Fügen Sie die Handler-Funktion:

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

WPF-Strings sollte dann richtig nach Kultur formatiert werden.

3

Wenn Sie eine bestimmte Sprache möchten, können Sie sie mit xml:lang auf dem obersten Element festlegen.

Zum Beispiel:

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

Ich weiß, dass dies eine alternde Frage, aber das hat für mich immer gearbeitet und den Austausch von Wissen ist eine gute Sache. Da meine Apps die Sprache immer im laufenden Betrieb ändern, ist die FrameworkElement.LanguageProperty.OverrideMetadata funktioniert nur einmal und seine nicht gut für mich, so siehe:

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

wo (this) ist die Mainwindow, Sie haben es tatsächlich in allen rootelements (Windows) zu tun. Da geht es einfach genug.