Принудительно ли всегда запускать Convert при использовании пользовательского конвертера в WPF? - PullRequest
1 голос
/ 23 апреля 2009

Я реализую пользовательский конвертер дат в WPF, идея быть более умной в отношении ввода даты, например Outlook (возможность ввода «сегодня» и т. Д.). Итак, я написал свой собственный конвертер, который за работой. Форматирует запись пользователя в формате M / d / yy. Так, например, если они введут: 8-2, они увидят 2/2/09. Прекрасный.

Вопрос в том, что пользователь может ввести несколько вещей, которые в конечном итоге приведут к одной и той же дате. (8-2 и 8/2, являющиеся простыми примерами). Итак, давайте просто скажем, что они начинают с ввода 8/2, который запускается через ConvertBack и Convert и отображается как 2/2/09. Все идет нормально. Теперь предположим, что они вводят 8-2 (или снова 8/2) в том же поле, сразу после этого. Он запускается через ConvertBack, который возвращает ОДНУ ЖЕ дату, которая уже есть в привязанном свойстве, поэтому он не беспокоится о запуске Convert, что означает, что "8/2" находится там в текстовом поле. Ик! Там нет проблем с данными, только дисплей, но эй, аккуратность имеет значение.

Как заставить WPF запускать Преобразование после ВСЕХ (без ошибок) записей?

Вот упрощенная версия конвертера:

    public class DateConverter : IValueConverter
{
    #region IValueConverter Members

    public object Convert(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
    {
        if (value != null)
        {
            string tempStr = value.ToString();
            return ((DateTime.Parse(tempStr)).ToString("M/d/yy"));
        }
        else
        {
            return null;
        }
    }

    public object ConvertBack(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
    {
        return DateTime.Parse(value.ToString());
    }

    #endregion
}

и вот как это выглядит:

      <local:FilteredTextBox.Text>
        <Binding Path="Value" ElementName="root" Converter="{StaticResource DateConv}" 
           UpdateSourceTrigger="LostFocus"  Mode="TwoWay" diagnostics:PresentationTraceSources.TraceLevel="High"
        NotifyOnValidationError="True" ValidatesOnDataErrors="True" ValidatesOnExceptions="True">
          <Binding.ValidationRules>
                <local:DateValidation/>
          </Binding.ValidationRules>
        </Binding>
      </local:FilteredTextBox.Text>

Спасибо! Скотт

В ответ на комментарий ниже, вот свойство поддержки:

      public DateTime? Value
    {
        get
        {
            return (DateTime?)GetValue(ValueProperty);
        }
        set
        {
            SetValue(ValueProperty, value);
            OnPropertyChanged(new DependencyPropertyChangedEventArgs(ValueProperty, null, value)); // I just added this line, it makes no difference
        }
    }

Ответы [ 2 ]

3 голосов
/ 23 апреля 2009

Возможно ли, что свойство данных поддержки запускается только PropertyChanged, если оно действительно меняет значение? Вы можете попробовать запустить PropertyChanged всякий раз, когда вызывается заданная функция, независимо от того, изменяется ли значение. Это приведет к обновлению привязки.

0 голосов
/ 24 апреля 2009

Большое спасибо Джошу Г. - с его помощью я разобрался (или, по крайней мере, с) ответом.

Это было для текстового поля внутри элемента управления DatePicker, который я создаю. Поэтому вместо того, чтобы «привязывать» текстовое поле непосредственно к значению элемента управления, я создал промежуточное свойство, которое затем вызывает набор для свойства зависимости:

  public DateTime? DateValue
    {
        get
        {
            return _dateValue;
        }
        set
        {
            _dateValue = value;
            OnPropertyChanged("DateValue");
            SetValue(ValueProperty, _dateValue);
        }
    }

и все работает как надо. Еще раз спасибо, Джош!

...