Вопрос:
У меня есть viewmodel, который содержит пару DateTime? object – nullable DateTimes.
private DateTime? _xmitdtFrom; public DateTime? xmitdtFrom { get { return this._xmitdtFrom; } set { this._xmitdtFrom = value; notifyPropertyChanged(«xmitdtFrom»); } } private DateTime? _xmitdtTo; public DateTime? xmitdtTo { get { return this._xmitdtTo; } set { this._xmitdtTo = value; notifyPropertyChanged(«xmitdtTo»); } }
Дата xmitdtFrom не может быть больше даты xmitdtFrom, дата xmitdtTo не может быть до даты xmitdtFrom, и ни xmitdtTo date, ни xmitdtFrom не может быть после сегодняшнего дня.
Итак, в разметке у меня есть:
<Label Grid.Row=»1″ Grid.Column=»1″> From: </Label> <DatePicker Grid.Row=»1″ Grid.Column=»2″ SelectedDate=»{Binding xmitdtFrom, Mode=TwoWay}» DisplayDateEnd=»{Binding xmitdtTo}» /> <Label Grid.Row=»2″ Grid.Column=»1″> Through: </Label> <DatePicker Grid.Row=»2″ Grid.Column=»2″ SelectedDate=»{Binding xmitdtTo, Mode=TwoWay}» DisplayDateStart=»{Binding xmitdtFrom}» DisplayDateEnd=»{x:Static sys:DateTime.Now}» />
И это отлично работает, если xmitdtTo не является нулевым – в этом случае xmitdtFrom не ограничен, что является проблемой.
Я хочу установить DisplayDateEnd для xmitdtFrom в xmitdtTo, если это не null или DateTime.Now, если это так.
И мне интересно, что может быть самым чистым способом добиться этого.
Лучший ответ:
Я решил пойти с другим подходом полностью.
Вместо того, чтобы возиться с viewmodel, я создал IfNullConverter, который, когда он используется в привязке, передал связанный объект, если он не был нулевым или передал свой ConversionParameter, если бы это было так.
И я использовал это в привязке с даты DisplayDateEnd – с xmitDTTo как свойство bound, а DateTime.Now – как ConversionParameter.
Решает проблему чисто, полностью в пользовательском интерфейсе (и это проблема пользовательского интерфейса, а не проблема с данными, поэтому я бы предпочел решение, которое не загрязняет модель просмотра). И он создает универсальную функциональность, которая будет доступна для использования в других подобных обстоятельствах.
Преобразователь:
public class IfNullConverter : IValueConverter { public object Convert(object value, Type targetType, object parameter, CultureInfo culture) { if (value == null) return parameter; else return value; } public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture) { throw new NotImplementedException(); } }
Связывание:
<DatePicker Grid.Row=»1″ Grid.Column=»2″ SelectedDate=»{Binding Path=xmitdtFrom, Mode=TwoWay}» DisplayDateEnd=»{Binding xmitdtThrough, Converter={StaticResource ifNullConverter}, ConverterParameter={x:Static sys:DateTime.Now}}» /> Ответ №1
Возможно, вы можете попробовать добавить другое свойство, с которым вы можете привязываться в DisplayDateEnd. Что-то вроде этого (непроверено):
private DateTime? _displayDateEnd; public DateTime? DisplayDateEnd { get { return this._displayDateEnd; } set { this._displayDateEnd = value; notifyPropertyChanged(«DisplayDateEnd»); }
Установите новое значение свойства из xmidtTo:
private DateTime? _xmitdtTo; public DateTime? xmitdtTo { get { return this._xmitdtTo; } set { this._xmitdtTo = value; if (_xmitdtTo == null) DisplayDateEnd = _xmitdtTo; else DisplayDateEnd = DateTime.Now(); notifyPropertyChanged(«DisplayDateEnd»); notifyPropertyChanged(«xmitdtTo»); } }
Ваш обновленный xaml:
<DatePicker … DisplayDateEnd=»{Binding DisplayDateEnd}»/> Ответ №2
Вам действительно нужно xmitdtTo быть нулевым? Я имею в виду, что вы не получаете или не сохраняете важные данные, когда он равен нулю, не так ли? Если это так, то я бы обошел всю проблему, установив _xmitdtTo на сегодняшний день по умолчанию.
private DateTime? _xmitdtTo = DateTime.Today;
Если вам нужно сохранить данные, вы можете изменить свойство вместо этого, чтобы вернуться сегодня, когда _xmitdtTo имеет значение null.
public DateTime? xmitdtTo { get { if (!_xmitdtTo.HasValue) return DateTime.Today; return this._xmitdtTo; }
Если вы действительно хотите сохранить нуль ваших данных, вы можете создать отдельное свойство в целом для вашего объекта, чтобы назначить DisplayDateEnd из xmitdtTo:
public DateTime xmitdtDateEnd { get { return _xmitdtTo ?? DateTime.Today; } }
Не забудьте добавить вызов notifyPropertyChanged (“xmitdtDateEnd”) в присваивание свойства xmitdtTo, чтобы обновить интерфейс при изменении xmitdtTo.
set { this._xmitdtTo = value; notifyPropertyChanged(«xmitdtTo»); notifyPropertyChanged(«xmitdtDateEnd»); }