2009-06-30 14 views
53

Ho qualche problema con l'output di un valore DateTime. La cultura attuale del mio computer è impostata su de-AT (Austria).WPF XAML StringFormat DateTime: output nella cultura errata?

Il codice seguente

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

risultati in s1 e s2 entrambe aventi il ​​valore corretto di "30.06.2009".

Ma quando si utilizza lo stesso formato in XAML

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

l'uscita è ` "2009/06/30". Sembra che XAML StringFormat ignori le impostazioni cultura correnti. Questo succede sia su Vista che su XP.

Non voglio specificare un formato personalizzato, perché l'output deve essere formattato nelle impostazioni cultura preferite dell'utente.

Chiunque abbia lo stesso problema? Si tratta di un bug in WPF?

+0

Ho giurato tutto il giorno, ho trovato questo problema all'ultimo minuto! – GorillaApe

+1

È considerato come "design". Vedere https://connect.microsoft.com/VisualStudio/feedback/details/442569/wpf-binding-uses-the-wrong-currentculture-by-default –

+0

ha appena visto lo stesso comportamento su Windows Phone 7. Saluti dall'Austria! – hfrmobile

risposta

1

si potrebbe usare un IValueConverter (che prende in un parametro di cultura) e formattare il valore che si desidera, qualcosa che mi piace è questo convertitore annullabile da 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 il original

9

ha scritto su di esso qualche tempo fa sul mio blog:

0.123.516,41 mila

Questo vi dirà come ottenere WPF per utilizzare la giusta cultura:

http://www.nbdtech.com/blog/archive/2009/02/22/wpf-data-binding-cheat-sheet-update-the-internationalization-fix.aspx

Questo cambierà la cultura WPF al volo quando si modificano le impostazioni nel pannello di controllo:

http://www.nbdtech.com/blog/archive/2009/03/18/getting-a-wpf-application-to-pick-up-the-correct-regional.aspx

12

per applicare la soluzione accennato http://tinyurl.com/b2jegna effettuare le seguenti operazioni:

(1) Aggiungere un nuovo inizio fino gestore di eventi per la classe Application in app.xaml:

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

(2) Aggiungere la funzione di gestione:

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

stringhe WPF dovrebbero quindi essere formattati correttamente in base alla cultura.

3

Se si desidera una lingua specifica, è possibile impostarla sull'elemento di livello superiore utilizzando xml:lang.

Ad esempio:

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

So che questa è una domanda di invecchiamento, ma questo ha sempre lavorato per me e per la condivisione della conoscenza è una buona cosa. Poiché le mie app cambiano sempre lingua al volo, FrameworkElement.LanguageProperty.OverrideMetadata funziona solo una volta e la sua non va bene per me, quindi ecco:

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

dove (questo) è il MainWindow, in realtà bisogna farlo in tutte le rootelements (Windows). Ci sei abbastanza semplice.