воскресенье, 31 августа 2014 г.

Binding Datatime to DatePicker

Проблема возникла когда я попытался связать объект типа DateTime к DatetimePicker.
В итоге обнаружил что в свойстве Date объекта типа DataPicker хранится значение типа , не совместимость типов DateTime и DateOffset навело на мысль что нужно как то преобразовывать одно в другое и обратно. Слава разработчикам microsoft! они позаботились о таких проблемах и реализовали специальный интерфейс IValueConverter у которого содержаться 2 метода: Convert и ConvertBack.
Convert - преобразует значение переданное при привязке в нашем случае это DataTime и преобразует его в DateOffset.
ConvertBack - наоборот DateOffset в DataTime.
!!!Конвертеры можно использовать практический для любых преобразований например дату в строку и наоборот.(еще был опыт что бы булевое значение конвертировать в Visibility свойство объекта)


Ниже приведены листинги исходного кода :
исходный код класса конвертера с использованием интерфейса(Листинг 1);
использование конвертера в xaml разметке(Листинг 2).

Листинг 1
class DateTimeToDateTimeOffset : IValueConverter
{
public object Convert(object value, Type targetType, object parameter, string language)
{
try
{
DateTime date = (DateTime)value;
return new DateTimeOffset(date);
}
catch (Exception ex)
{
return DateTimeOffset.MinValue;
}
}

public object ConvertBack(object value, Type targetType, object parameter, string language)
{
try
{
DateTimeOffset dto = (DateTimeOffset)value;
return dto.DateTime;
}
catch (Exception ex)
{
return DateTime.MinValue;
}
}
}

Пояснение к Листингу 1.
Как видно в коде реализуется интерфейс IValueConverter и 2 метода.(об их назначении было указанно ранее).

Листинг 2
<xmlns:cnvrt="myproject.converters"/>
...
<PageResources>
 <cnvrt:DateTimeToDateTimeOffset x:key="DateTimeToDateTimeOffset"/>
</PageResources>
...
<DatePicker Header="Date" x:Name="dtpDate" Date="{Binding DateTimeProp, Converter={StaticResource DateTimeToDateTimeOffset},UpdateSourceTrigger=PropertyChanged, Mode=TwoWay}" />

Пояснение к Листингу 2.
Для начало в разметке страницы нужно подключить пространство имен содержащее нужный конвертер. После подключения нужного пространства имен необходимо создать экземпляр конвертера и дать ему контекстное ключ x:key="DateTimeToDateTimeOffset".
После проделанных ранее действий можем привязывать нужной свойство с типом DateTime к DatePicker. Остановимся на самом способе привязки.
Первым делом мы должны объявить атрибут с которым хотим связать значение в данном примере это Date, конструкция связки заключается в фигурные скобки следом идет команда Binding после объект который мы хотим связать (DateTimeProp) после через запятую объявляем что нужно использовать конвертер Converter={StaticResource DateTimeToDateTimeOffset}
Обратите внимание на UpdateSourceTrigger=PropertyChanged данная строка означает что при смене свойства будет идти обновление как в элементе управления так и в привязанном объектом. Mode=TwoWay говорит о том что изменение в объекте или элементе управлиния повлекут за собой изменения в другом объекте(имею ввиду что при изменении значения в через GUI изменется значения связанного объекта и при изменении объекта в коде значение в GUI поменяется автоматический).

Вы можете аналогично написать конвертер TimeToTimeSpan и использовать его для TimePicker.
А что на счет связки DateTime к TimePicker?(для редактирования даты и времени одного объекта типа DateTime через DatePicker и TimePicker можно прочитать здесь)

Материалы:
Binding to the new XAML DatePicker and TimePicker controls to the same DateTime value

Комментариев нет:

Отправить комментарий