Поведение автокоррекции на объектах datetime с привязкой к XAML начиная с .NET 4.0? - PullRequest
10 голосов
/ 15 июня 2011

При переносе приложения из .NET 3.5 в .NET 4.0 я столкнулся с этой специфической проблемой.

(культура nl-BE)

Я привязываю TextBox следующим образом (в XAML) в значение DateTime с UpdateSourceTrigger в PropertyChanged (LostFocus работает, как и ожидалось, но требуется проверка по мере ввода):

<TextBox Height="23" Margin="146,0,105,97.04" Name="txb_Geboortedatum" VerticalAlignment="Bottom">
        <TextBox.Text>
            <Binding Path="Geboortedatum" StringFormat="d" 
                     UpdateSourceTrigger="PropertyChanged">
                <Binding.ValidationRules>
                    <ExceptionValidationRule />
                </Binding.ValidationRules>
            </Binding>
        </TextBox.Text>
</TextBox>

Теперь, когда содержимое этого текстового поля (например) 10/12/2000 , и я хочу изменить его на 09/03/1981 Некоторая неприятная автокоррекция происходит , когда я помещаю курсор в конец2000 и начните 'backspacing', удалив значение года (когда только первая цифра ('2') из '2000' автоматически оставит значение - включая переход курсора - снова изменится на 2002).Можно ли отключить эту автокоррекцию?

Кажется, я не могу найти, что конкретно ввело это поведение.Та же «проблема» также возникает с FormatString=c для значений валюты.

То, что я пробовал до сих пор:

  1. Изменение FormatString на что-то более явное, например {0}{dd/MM/yyyy} (та же проблема: начинается автоматическое исправление, когда для года осталось 2 цифры).
  2. Отключение следующего фрагмента, который я добавил в свой файл App.xaml.cs:

    FrameworkElement.LanguageProperty.OverrideMetadata(
        typeof(FrameworkElement), 
        new FrameworkPropertyMetadata(XmlLanguage.GetLanguage(
            CultureInfo.CurrentCulture.IetfLanguageTag)));
    

Обоснование того, что этот фрагмент должен быть включен в первую очередь: посмотрите на эту ссылку .

Я что-то упускаю здесь очевидное?Я не могу воспроизвести это в 3.5.Мне действительно нужно свернуть свои собственные ValueConverters для того, чтобы заставить это работать должным образом?Это похоже на шаг назад по сравнению с StringFormat, который был введен в 3.5 sp 1.

Вывод из DateTimeFormatInfo.CurrentInfo.GetAllDateTimePatterns('d') выглядит немного иначе, хотя ничего, что могло бы сразу объяснить поведение (возможно, не связанное):

.NET 3.5        .NET 4.0

d/MM/yyyy       d/MM/yyyy
d/MM/yy         d/MM/yy
dd-MM-yy        dd-MM-yy
dd.MM.yy        dd.MM.yy
yyyy-MM-dd      dd.MMM.yyyy
                yyyy-MM-dd

Ответы [ 3 ]

3 голосов
/ 15 июня 2011

В настоящее время я использовал что-то подобное, но меня очень интересовали бы другие подходы для решения вышеуказанной проблемы:

public class CustomDateTimeConverter : IValueConverter
{
    public object Convert(object value, Type targetType, object parameter, 
                          CultureInfo culture)
    {
        if (value == null) { return ""; }
        DateTime dt;
        if (DateTime.TryParse(value.ToString(), CultureInfo.CurrentCulture, 
                              DateTimeStyles.None, out dt))
        {
            return dt.ToShortDateString();
        }
        return "";
    }

    public object ConvertBack(object value, Type targettype, object parameter, 
                              CultureInfo culture)
    {
        if (value == null || value.ToString().Trim().Length==0) { return null; }
        string frmt = CultureInfo.CurrentCulture.DateTimeFormat.ShortDatePattern;
        DateTime dt;
        if (DateTime.TryParseExact(value.ToString(), frmt, 
                                   CultureInfo.CurrentCulture, 
                                   DateTimeStyles.None, out dt))
        {
            return dt;
        }
        return DependencyProperty.UnsetValue;
    }
}
3 голосов
/ 04 июля 2011

Ну, это нормальное поведение, если вы автоматически исправляете в PropertyChanged. При запуске возврата назад значение, передаваемое конструктору DateTime, равно:

Экран >> DateTime (' | ' - это расположение курсора перед каждым возвратом )

10-12-2000| >> DateTime(200,12,10) >> 10-12-0200

10-12-020|0 >> DateTime(020,12,10) >> 10-12-020 

10-12-00|20  >> DateTime(020,12,10) >> 10-12-020 

10-12-0|20 >> DateTime(20,12,10) >> 10-12-2020

(я думаю, это может варьироваться в зависимости от вашей культуры из-за формата гг-мм-дд )

жестко, я не совсем понимаю, почему новый DateTime (20,12,10) указывает на 2020 год для меня в текстовом поле. Когда я использую DateTime.Parse (20,12,10), это приводит меня к 2012-10-20 (гггг-мм-дд). Там должно быть какое-то автоматическое преобразование или анализ, который мы не можем контролировать, если не используем пользовательский ValueConvertor

Я думаю, что пользовательский конвертер - это хороший способ, если вам абсолютно необходима «проверка по типу» , иначе OnLostFocus работает хорошо, как вы сказали.

Кстати, моя культура en-US

1 голос
/ 15 июня 2011

Вы пробовали использовать элемент управления DatePicker?

http://msdn.microsoft.com/en-us/library/system.windows.controls.datepicker.aspx

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