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

guz6ccqo  于 2023-04-27  发布在  其他
关注(0)|答案(6)|浏览(119)

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

输出为“6/30/2009”。似乎XAML字符串格式忽略了当前的区域性设置。这在Vista和XP上都发生。
我不想指定自定义格式,因为输出应该按照用户的首选区域性设置进行格式化。
有人有同样的问题吗?这是WPF中的bug吗?

ohfgkhjo

ohfgkhjo1#

请看我对StringFomat本地化问题的回答

qlckcl4x

qlckcl4x2#

要应用提到的here解决方案,请执行以下操作:
(1)将Startup事件处理程序添加到app.xaml中的Application类:

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

(2)添加handler函数:

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

然后,WPF字符串应根据区域性正确格式化。

fslejnso

fslejnso4#

如果你想要一种特定的语言,你可以使用xml:lang在顶层元素上设置它。
例如:

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

i86rm4rw5#

我知道这是一个老化的问题,但这对我来说一直很有效,分享知识是一件好事。由于我的应用程序总是动态更改语言,FrameworkElement.LanguageProperty.OverrideMetadata只工作一次,对我没有好处,所以请注意:

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

这里是主窗口,实际上你必须在所有的根元素(窗口)中做。这样就足够简单了。

9lowa7mx

9lowa7mx6#

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

相关问题