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

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/1062160/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-06 07:18:49  来源:igfitidea点击:

WPF XAML StringFormat DateTime: Output in wrong culture?

c#wpfxamldatetime

提问by Christian Hubmann

I'm having some trouble with the output of a DateTime value. My computer's current culture is set to de-AT (Austria).

我在输出 DateTime 值时遇到了一些问题。我计算机的当前区域性设置为 de-AT(奥地利)。

The following code

以下代码

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

results in s1 and s2 both having the correct value of "30.06.2009".

结果 s1 和 s2 都具有正确的值“30.06.2009”。

But when using the same format in XAML

但是当在 XAML 中使用相同的格式时

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

the output is `"6/30/2009". It seems the XAML StringFormat ignores the current culture settings. This happens on both Vista and XP.

输出是“6/30/2009”。XAML StringFormat 似乎忽略了当前的区域性设置。这发生在 Vista 和 XP 上。

I don't want to specify a custom format, because the output should be formatted in the user's preferred culture setting.

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

Anybody with the same problem? Is this a bug in WPF?

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

回答by almog.ori

you could use a IValueConverter (which takes in a culture parameter) and format the value as you wish, something I like is this nullable converter by Matt Hamilton

您可以使用 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

}

}

heres the original

这是原版

回答by Nir

Wrote about it some time ago on my blog:

前段时间在我的博客上写过:

This will tell you how to get WPF to use the right culture:

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

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

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

This will change the WPF culture on the fly when you modify the settings in the control panel:

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

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

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

回答by Stephen Holt

To apply the solution mentioned at http://tinyurl.com/b2jegnado the following:

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

(1) Add a Startup event handler to the Application class in app.xaml:

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

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

(2) Add the handler function:

(2) 添加处理函数:

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

WPF strings should then be formatted correctly according to culture.

然后应根据文化正确设置 WPF 字符串的格式。

回答by Domysee

If you want one particular language, you can set it on the top level element using xml:lang.

如果你想要一种特定的语言,你可以使用xml:lang.

For example:

例如:

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

回答by Nemesis

I Know that this is an aging question but this has always worked for me and sharing knowledge is a good thing. Since my apps always change language on the fly, the FrameworkElement.LanguageProperty.OverrideMetadata only works once and its no good for me, so behold:

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

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

where (this) is the MainWindow, actually you have to do it in all rootelements (Windows). There you go simple enough.

其中 (this) 是 MainWindow,实际上您必须在所有根元素 (Windows) 中执行此操作。你去够简单了。