2009-06-30 26 views
53

我在输出DateTime值时遇到了一些麻烦。我的电脑目前的文化设置为de-AT(奥地利)。WPF XAML StringFormat DateTime:输出错误的文化?

以下代码

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

结果S1和S2两者都具有 “30.06.2009” 的正确的值。

但在XAML

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

使用相同格式时的输出是' “6/30/2009”。看来XAML StringFormat忽略了当前的文化设置。这发生在Vista和XP上。

我不想指定自定义格式,因为输出应该在用户的首选文化设置中格式化。

任何人都有同样的问题?这是WPF中的错误吗?

+0

我发誓整天都在,我发现这个问题最后一分钟! – GorillaApe 2010-10-12 06:20:03

+1

它被认为是“通过设计”。请参阅https://connect.microsoft.com/VisualStudio/feedback/details/442569/wpf-binding-uses-the-wrong-currentculture-by-default – 2010-12-01 09:21:31

回答

1

你可以使用的IValueConverter(这需要在文化参数),并根据需要设置值的格式,这是我喜欢的是由Matt汉密尔顿

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 

}

继承人的original这可空转换器

12

申请在http://tinyurl.com/b2jegna提到的解决方案做到以下几点:

(1)添加一个启动达事件处理程序中的应用类的App.xaml:

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

(2)添加的处理函数:

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

WPF串然后应根据培养正确格式化。

3

如果您需要某种特定语言,则可以使用xml:lang将其设置在顶层元素上。

例如:

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

我知道,这是一个老问题,但这个一直为我工作和分享知识是一件好事。由于我的应用程序总是随时更改语言,FrameworkElement.LanguageProperty。OverrideMetadata只能使用一次其不适合我,所以你看:

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

其中(这)是主窗口,实际上是你必须做的所有rootelements(Windows)中。 你有那么简单。