Подтвердить что ты не робот

WPF XAML StringFormat DateTime: выход из неправильной культуры?

У меня возникают проблемы с выходом значения DateTime. Текущая культура компьютера установлена ​​в де-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 StringFormat игнорирует текущие настройки культуры. Это происходит как на Vista, так и на XP.

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

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

4b9b3361

Ответ 2

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

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

Ответ 3

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

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

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

Например:

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

Ответ 5

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

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

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

Ответ 6

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