C#/WPF - How to enable only a specific set of dates(not a range) in a DatePicker object

Viewed 350

I have a list of dates I would like the user to select from. These dates are not sequentially right after each other and can be scattered thought a given period of time. Because of the dates being in a scattered nature, I can not use the "DisplayDateStart" and "DisplayDateEnd" properties of the WPF "DatePicker" control. Is there a way I can make the date picker grey out all other dates that are not in a given list. Below is snippet of "pseudo" code demonstrating what I would like to accomplish.

    public void foo(List<DateTime> ldtData, DatePicker dpPicker) {
        dpPicker.EnabledDates = ldtData; // What I would like to do in a perfect world (:
    }
1 Answers

There is no EnabledDates property. There is a BlackoutDates property to which you can add dates that are not selectable.

But if you bind to a list of selectable dates, you could use a CalendarDayButtonStyle and a converter to determine whether a particular date should be selectable:

public class DateToBoolConverter : IMultiValueConverter
{
    public object Convert(object[] values, Type targetType, object parameter, CultureInfo culture)
    {
        if (values == null || values.Length < 2)
            return true;

        IList<DateTime> selectableDates = values[0] as IList<DateTime>;
        if (selectableDates == null)
            return true;

        DateTime currentDate = (DateTime)values[1];
        return selectableDates.Contains(currentDate);
    }

    public object[] ConvertBack(object value, Type[] targetTypes, object parameter, CultureInfo culture)
    {
        throw new NotSupportedException();
    }
}

XAML:

<DatePicker x:Name="dpPicker">
    <DatePicker.CalendarStyle>
        <Style TargetType="Calendar">
            <Setter Property="CalendarDayButtonStyle">
                <Setter.Value>
                    <Style TargetType="CalendarDayButton">
                        <Style.Resources>
                            <local:DateToBoolConverter x:Key="DateToBoolConverter" />
                        </Style.Resources>
                        <Setter Property="IsHitTestVisible" Value="False" />
                        <Setter Property="Opacity" Value="0.5" />
                        <Style.Triggers>
                            <DataTrigger Value="True">
                                <DataTrigger.Binding>
                                    <MultiBinding Converter="{StaticResource DateToBoolConverter}">
                                        <Binding Path="Tag" RelativeSource="{RelativeSource AncestorType=DatePicker}" />
                                        <Binding Path="." />
                                    </MultiBinding>
                                </DataTrigger.Binding>
                                <Setter Property="IsHitTestVisible" Value="True" />
                                <Setter Property="Opacity" Value="1" />
                            </DataTrigger>
                        </Style.Triggers>
                    </Style>
                </Setter.Value>
            </Setter>
        </Style>
    </DatePicker.CalendarStyle>
</DatePicker>

Sample usage:

public void foo(List<DateTime> ldtData, DatePicker dpPicker)
{
    dpPicker.Tag = ldtData;
}
Related