Свойство DateTime не запускает событие PropertyChanged при изменении - PullRequest
2 голосов
/ 15 апреля 2010

Я работаю над приложением WPF MVVM, и у меня есть TextBox, который привязан к свойству DateTime в ViewModel. Кажется достаточно простым, но когда я очищаю текст в TextBox, свойство никогда не меняется. На самом деле, он даже не срабатывает, пока я не начну печатать "4/1 ...", а затем он срабатывает. Что я могу сделать, чтобы это исправить? Очевидно, что я мог бы связать TextBox со строковым свойством, а затем обновить реальное свойство в установщике, но это немного хак. Должен быть лучший способ ...

ViewModel

private DateTime _startDate;
public DateTime StartDate
{
    get { return _startDate; }
    set
    {
        _startDate = value;
        OnPropertyChanged("StartDate");
    }
}

View

<TextBox Text="{Binding Path=StartDate, 
               UpdateSourceTrigger=PropertyChanged, 
               ValidatesOnDataErrors=true}"/>

1 Ответ

3 голосов
/ 15 апреля 2010

Это зависит от того, что вы хотите, чтобы содержимое текстового поля не являлось допустимым DateTime. Пустая строка не может быть проанализирована как DateTime, поэтому, когда вы очищаете текстовое поле, WPF не знает, какое значение нужно вернуть обратно в ваш источник привязки, поэтому ничего не делает, и ваш установщик не получает запустить. Как только вы наберете достаточно для разбора, WPF запустит программу и снова начнет обновление, поэтому ваше событие PropertyChanged снова запустится. Поэтому первое, что вам нужно сделать, это решить, какое значение DateTime вы хотите, когда текст пуст или не разбирается.

Как только вы это сделаете, вы можете создать IValueConverter:

// Simplified, ignoring error checking, etc.
public class DateTimeConverter : IValueConverter
{
  // For source -> target (DateTime -> string) conversion
  public object Convert(object value...)
  {
    return value.ToString();  // ignoring culture, date-time format, etc.
  }

  // For target -> source (string -> DateTime) conversion
  public object ConvertBack(object value...)
  {
    string str = (string)value;
    DateTime dt = GetDateTimeFromMaybePartialString(str);  // your logic here
    return dt;
  }
}

и вставьте это в переплет:

<Window.Resources>
  <local:DateTimeConverter x:Key="dtc" />
</Window.Resources>

<TextBox Text="{Binding Path=StartDate, 
                        Converter={StaticResource dtc},
                        UpdateSourceTrigger=PropertyChanged, 
                        ValidatesOnDataErrors=true}"/>
...