WPF XAML StringFormat DateTime: вывод в неправильной культуре? - PullRequest
61 голосов
/ 30 июня 2009

У меня проблемы с выводом значения 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}"/>

вывод будет "" 30.06.2009 ".Похоже, XAML StringFormat игнорирует текущие настройки культуры.Это происходит как в Vista, так и в XP.

Я не хочу указывать пользовательский формат, потому что вывод должен быть отформатирован в соответствии с предпочтительными настройками пользователя.

У кого-нибудь есть такая же проблема?Это ошибка в WPF?

Ответы [ 6 ]

41 голосов
/ 30 июня 2009
14 голосов
/ 16 мая 2013

Чтобы применить решение, указанное в http://tinyurl.com/b2jegna, сделайте следующее:

(1) Добавьте обработчик события запуска в класс Application в 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 должны быть правильно отформатированы в соответствии с культурой.

9 голосов
/ 30 июня 2009

Написал об этом некоторое время назад в моем блоге:

Это скажет вам, как заставить 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

4 голосов
/ 02 октября 2015

Если вам нужен один конкретный язык, вы можете установить его на элементе верхнего уровня, используя xml:lang.

Например:

<Window xml:lang="de-AT">
...
</Window>
3 голосов
/ 02 июня 2016

Я знаю, что это вопрос старения, но он всегда работал для меня, и обмен знаниями - это хорошо. Поскольку мои приложения всегда меняют язык на лету, FrameworkElement.LanguageProperty.OverrideMetadata работает только один раз, и это мне не подходит, так что вот:

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

где (это) MainWindow, на самом деле вы должны сделать это во всех элементах root (Windows). Там вы идете достаточно просто.

1 голос
/ 30 июня 2009

вы могли бы использовать IValueConverter (который принимает параметр культуры) и отформатировать значение, как вы хотите, мне нравится этот конвертируемый Nullable от 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

}

вот оригинал

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...