WPF XAML StringFormat DateTime:输出错误的文化?

时间:2009-06-30 07:07:44

标签: c# wpf xaml datetime

我在输出DateTime值时遇到了一些麻烦。我的计算机目前的文化设置为de-AT(奥地利)。

以下代码

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}"/>

输出为“2009年6月30日”。似乎XAML StringFormat忽略了当前的文化设置。这种情况发生在Vista和XP上。

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

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

6 个答案:

答案 0 :(得分:40)

答案 1 :(得分:13)

要应用http://tinyurl.com/b2jegna中提到的解决方案,请执行以下操作:

(1)将一个Startup事件处理程序添加到app.xaml中的Application类:

<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字符串。

答案 2 :(得分:9)

不久前在我的博客上写过:

这将告诉您如何让WPF使用正确的文化:

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

当您修改控制面板中的设置时,这将动态更改WPF文化:

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

答案 3 :(得分:4)

如果您需要一种特定语言,可以使用xml:lang在顶级元素上进行设置。

例如:

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

答案 4 :(得分:3)

我知道这是一个老化的问题,但这一直对我有用,分享知识是一件好事。由于我的应用程序总是随时更改语言,因此FrameworkElement.LanguageProperty.OverrideMetadata只能运行一次,对我来说没什么用,所以看看:

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

其中(this)是MainWindow,实际上你必须在所有的rootelements(Windows)中执行它。 你就够简单了。

答案 5 :(得分:1)

你可以使用IValueConverter(它接受一个culture参数)并根据你的意愿格式化值,我喜欢的是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

}

继承人original