Фикс обхода максимального и минимального заданного интервала в DatePicker
Есть следующий конвертер:
public class DatePickerConverter : IValueConverter
{
public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
{
return DateTime.Now.AddDays(-3);
}
public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
{
throw new NotImplementedException();
}
}
И вот такой вот xaml:
<DatePicker
DisplayDateStart="{Binding Source={StaticResource datePickerConverter}, Path=., Converter={StaticResource datePickerConverter}}"
DisplayDateEnd = "{Binding Source={x:Static sys:DateTime.Now}, Path=.}">
</DatePicker>
И вроде бы всё нормально, нужный интервал готов.
Однако, если вручную в DatePicker вписать рандомную дату, то сразу же появляется новый интервал которого не должно быть в принципе.
Как данный баг устранить?
Ответы (1 шт):
Во-первых, у вас странная привязка к конвертеру. Привязка должна быть к свойству, свойство передается в аргумент конвертера.
Конвертер должен выглядеть вот так, если уж решили его делать, хотя я бы обошелся дополнительным свойством.
public class DatePickerConverter : IValueConverter
{
public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
{
return ((DateTime)value).AddDays(-3);
}
public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
{
throw new NotSupportedException();
}
}
Я бы, кстати, это -3 унес в разметку и передавал бы как ConverterParameter из XAML привязки. Тогда не придется переписывать конвертер, если появится потребность разные интервалы для разных пикеров задавать.
Затем создать свойство во вьюмодели для выбранной даты
public DateTime SelectedDate { get; set; } = DateTime.Today;
И тогда получится вот такая верстка
<DatePicker
DisplayDateStart="{Binding Source={x:Static sys:DateTime.Today}, Converter={StaticResource datePickerConverter}, Mode=OneTime}"
DisplayDateEnd="{Binding Source={x:Static sys:DateTime.Today}, Mode=OneTime}"
SelectedDate="{Binding SelectedDate}">
<DatePicker.Resources>
<Style TargetType="DatePickerTextBox">
<Setter Property="IsReadOnly" Value="True"/>
</Style>
</DatePicker.Resources>
</DatePicker>
То есть просто выключить текстовый ввод. Пользователю только останется выбрать дату.
В этом плане мне нравится WinUI 3 (Windows App SDK), там то же самое можно получить вот таким образом, то есть CalendarDatePicker не позволяет текстовый ввод по умолчанию, да и выглядит поприкольнее.
<CalendarDatePicker MinDate="{x:Bind sys:DateTime.Today.AddDays(-3)}"
MaxDate="{x:Bind sys:DateTime.Today}"
Date="{x:Bind ViewModel.SelectedDate, Mode=TwoWay}"
FirstDayOfWeek="Monday"/>
Жаль, что в остальном там не все так прикольно, и WPF пока выглядит в разы мощнее.


