WPF XAML StringFormat DateTime:输出的区域设置错误?

69
我在处理 DateTime 值的输出时遇到了一些问题。我的电脑当前的区域设置为 de-AT(奥地利)。
以下是代码:
string s1 = DateTime.Now.ToString("d");
string s2 = string.Format("{0:d}", DateTime.Now);

使用相同的格式在 XAML 中时,会导致 s1 和 s2 都具有正确的值 "30.06.2009"。

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

输出结果为“6/30/2009”。看起来,XAML StringFormat 忽略了当前的区域设置。这在 Vista 和 XP 上都发生了。

我不想指定自定义格式,因为输出应该按用户偏好的区域设置进行格式化。

有相同问题的人吗?这是 WPF 的一个 bug 吗?


我整天都在努力,最后一分钟才发现这个问题! - GorillaApe
1
这被认为是“按设计要求的”。请参见https://connect.microsoft.com/VisualStudio/feedback/details/442569/wpf-binding-uses-the-wrong-currentculture-by-default。 - Daniel Rose
刚在Windows Phone 7上看到了相同的行为。来自奥地利的问候! - hfrmobile
6个回答

44

4
如果你覆盖默认设置,这并没有帮助。 - GorillaApe

17

要应用此处提到的解决方案,请执行以下操作:

(1) 在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字符串应根据文化正确格式化。


10
如果您想要使用特定语言,可以在顶级元素中使用xml:lang进行设置。
例如:
<Window xml:lang="de-AT">
...
</Window>

10

3

我知道这是一个老问题,但这对我一直有效,分享知识是一件好事。由于我的应用程序总是在运行时更改语言,FrameworkElement.LanguageProperty.OverrideMetadata只能工作一次,并且对我来说没有用,所以请看:

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

这里的 (this) 是指 MainWindow,实际上你需要在所有根元素(Windows)中都这样做。


1

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

}

这里是原始链接


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接