2009-06-30 32 views
53

Tôi đang gặp một số sự cố với đầu ra của giá trị Ngày giờ. Văn hóa hiện tại của máy tính của tôi được đặt thành de-AT (Áo).WPF XAML StringFormat DateTime: Đầu ra trong văn hóa sai?

Các mã sau

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

kết quả trong s1 và s2 cả có giá trị chính xác của "2009/06/30".

Nhưng khi sử dụng định dạng tương tự trong XAML

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

đầu ra là ` "2009/06/30". Dường như XAML StringFormat bỏ qua các thiết lập văn hóa hiện tại. Điều này xảy ra trên cả Vista và XP.

Tôi không muốn chỉ định định dạng tùy chỉnh, vì đầu ra phải được định dạng trong cài đặt văn hóa ưa thích của người dùng.

Bất kỳ ai có cùng sự cố? Đây có phải là một lỗi trong WPF?

+0

Tôi thề cả ngày, tôi đã tìm thấy vấn đề này vào phút cuối! – GorillaApe

+1

Nó được coi là "theo thiết kế". Xem https://connect.microsoft.com/VisualStudio/feedback/details/442569/wpf-binding-uses-the-wrong-currentculture-by-default –

+0

chỉ thấy hành vi tương tự trên Windows Phone 7. Lời chào từ Áo! – hfrmobile

Trả lời

1

bạn có thể sử dụng một IValueConverter (mất trong một tham số nền văn hóa) và định dạng giá trị như bạn muốn, cái gì tôi thích là chuyển đổi nullable này 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 original

9

Wrote về nó một thời gian trước trên blog của tôi:

này sẽ cho bạn biết làm thế nào để có được WPF sử dụng văn hóa phải:

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

này sẽ thay đổi văn hóa WPF on the fly khi bạn sửa đổi các thiết lập trong bảng điều khiển:

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

12

Để áp dụng các giải pháp nêu tại http://tinyurl.com/b2jegna làm như sau:

(1) Thêm một Bắt đầu lên xử lý sự kiện cho lớp ứng dụng trong App.xaml:

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

(2) Thêm chức năng xử lý:

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

WPF chuỗi sau đó nên được định dạng đúng theo văn hóa.

3

Nếu bạn muốn một ngôn ngữ cụ thể, bạn có thể đặt ngôn ngữ đó ở phần tử cấp cao nhất bằng cách sử dụng xml:lang.

Ví dụ:

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

tôi biết rằng đây là một câu hỏi lão hóa nhưng điều này đã luôn luôn làm việc cho tôi và chia sẻ kiến ​​thức là một điều tốt. Vì các ứng dụng của tôi luôn thay đổi ngôn ngữ khi đang bay, nên FrameworkElement.LanguageProperty.OverrideMetadata chỉ hoạt động một lần và nó không tốt đối với tôi, vì vậy kìa:

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

nơi (this) là MainWindow, thực sự bạn phải làm điều đó trong tất cả rootelements (Windows). Có bạn đi đủ đơn giản.

Các vấn đề liên quan