#1,038 – Another Way to Prevent Certain Dates from Being Selected

You can limit the dates available for selection in a Calendar or DatePicker control in a few different ways.

If you want to prohibit some combination of dates, but have to do some calculation to figure out which dates should be prohibited, you can add a handler for the SelectedDateChanged event.

        <Label Content="Pick a day to go skydiving:"
               Margin="5"/>
        <DatePicker Margin="5,0,5,5"
                    SelectedDateChanged="DatePicker_SelectedDateChanged" />

In the handler, if the selected date is not one that you allow, you can undo the fact that it was selected.

        private void DatePicker_SelectedDateChanged(object sender, System.Windows.Controls.SelectionChangedEventArgs e)
        {
            if (e.AddedItems.Count > 0)
            {
                DateTime dayToDive = (DateTime)e.AddedItems[0];
                if ((dayToDive.DayOfWeek == DayOfWeek.Friday) &&
                    (dayToDive.Day == 13))
                {
                    MessageBox.Show("Dude, that's really an unlucky day to go skydiving.");
                    ((DatePicker)sender).SelectedDate = null;
                }
            }
        }

If we pick a Friday the 13th, the application warns us and then unselects the date.
1038-001

 

1038-002

#1,034 – Limiting the Range of Selectable Dates in a Calendar

The Calendar control allows selecting one or more dates.  By default, the user is allowed to select dates within the range DateTime.MinValue (1/1/0001) to DateTime.MaxValue (12/31/9999).

If you want to restrict the user to dates within a more reasonable range, you can set the DisplayDateStart and DisplayDateEnd properties.  The Calendar will then be limited to dates within that range.

        <Label Content="Pick your favorite day from the 1980s:"/>
        <Calendar DisplayDateStart="1/1/1980"
                  DisplayDateEnd="12/31/1989"/>

1034-001
1034-002

These properties also work in the DatePicker control, to limit the dates that can be selected.

 

#371 – Specifying a Default Date for a Calendar Control to Display

When you use a Calendar control, it will default to showing the current date when the application starts.

You can override the default date displayed by setting the DisplayDate property.

        <Calendar SelectionMode="SingleDate" DisplayDate="7/20/1969"/>


You can also specify a range of dates that the Calendar control is allowed to display by using the DisplayDateStart and DisplayDateEnd properties.

        <Calendar SelectionMode="SingleDate" DisplayDateStart="12/7/1941" DisplayDateEnd="8/14/1945"/>

The Calendar control will now allow selecting only dates that fall within this time period.  When you navigate to the month containing the earliest date, you’ll be unable to navigate further back in time.  Similarly, you’ll be unable to navigate to a date later than the date specified in the DisplayDateEnd property.


#368 – Specifying Blackout Dates in a Calendar Control

You can use the BlackoutDates property of a Calendar control to specify dates that a user cannot select.

The BlackoutDates property is of type CalendarBlackoutDatesCollection, which is an observable collection of CalendarDateRange objects.  You can specify a set of blackout dates for a Calendar control in XAML by defining a series of CalendarDateRange instances.

        <Calendar Name="calMuseum" SelectionMode="SingleDate">
            <Calendar.BlackoutDates>
                <CalendarDateRange Start="8/6/11" End="8/7/11"/>
                <CalendarDateRange Start="8/20/11" End="8/20/11"/>
                <CalendarDateRange Start="8/28/11" End="8/30/11"/>
            </Calendar.BlackoutDates>
        </Calendar>
        <Label Content="Choose a day to visit the museum." HorizontalContentAlignment="Center" />

The dates specified as blackout dates are not selectable by a user and will appear x‘d out on the calendar.

You can also add specific blackout dates from code-behind.

            // Blackout holidays
            calMuseum.BlackoutDates.Add(new CalendarDateRange(new DateTime(2011,1,17)));
            calMuseum.BlackoutDates.Add(new CalendarDateRange(new DateTime(2011,2,21)));
            calMuseum.BlackoutDates.Add(new CalendarDateRange(new DateTime(2011,5,30)));
            calMuseum.BlackoutDates.Add(new CalendarDateRange(new DateTime(2011,7,4)));
            calMuseum.BlackoutDates.Add(new CalendarDateRange(new DateTime(2011,9,5)));
            calMuseum.BlackoutDates.Add(new CalendarDateRange(new DateTime(2011,10,10)));
            calMuseum.BlackoutDates.Add(new CalendarDateRange(new DateTime(2011,11,11)));
            calMuseum.BlackoutDates.Add(new CalendarDateRange(new DateTime(2011,11,24)));
            calMuseum.BlackoutDates.Add(new CalendarDateRange(new DateTime(2011,12,26)));

#367 – You Can’t Bind to a Calendar Control’s SelectedDates Property

A Calendar control’s SelectedDate property (single selected date) is read/write, so you are able to use data binding to bind it to a nullable DateTime.

The SelectedDates property (collection of selected dates), on the other hand, is read-only.  This means that you can’t bind to the SelectedDates property.

If you want to store a Calendar control’s set of currently selected dates in a variable, you can handle the calendar’s SelectedDatesChanged event.

XAML fragment:

        <Calendar SelectionMode="MultipleRange" SelectedDatesChanged="Calendar_SelectedDatesChanged"/>

Code-behind, where we store selected dates in array:

        public DateTime[] MyVacation { get; set; }

        private void Calendar_SelectedDatesChanged(object sender, SelectionChangedEventArgs e)
        {
            System.Windows.Controls.Calendar cal = (System.Windows.Controls.Calendar)sender;

            MyVacation = cal.SelectedDates.ToArray();
        }

This event handler will be called whenever the user selects or unselects dates in the Calendar control.  Because we reset the MyVacation array in the handler, it will always reflect the current set of selected dates.

#366 – Binding a Calendar Control’s SelectedDate Property to a Nullable DateTime

The SelectedDate property of a Calendar control reflects the currently selected date, if the SelectionMode is SingleDate, or the first date selected if the mode is SingleRange or MultipleRange.

You can use data binding to bind the SelectedDate property to a variable of type DateTime? (nullable DateTime).

In the example below, we bind SelectedDate to the FavoriteDay property of our data context.

    <StackPanel>
        <Calendar SelectionMode="SingleDate" SelectedDate="{Binding FavoriteDay}"/>
        <Button Content="Test" Click="Button_Click" Width="80" Margin="20"/>
    </StackPanel>

In the code-behind, we define the FavoriteDay property and set the data context to the parent class that contains the property.

        public DateTime? FavoriteDay { get; set; }

        public MainWindow()
        {
            this.InitializeComponent();
            this.DataContext = this;
        }

        private void Button_Click(object sender, RoutedEventArgs e)
        {
            string msg;

            if (FavoriteDay == null)
                msg = "I don't have a favorite day";
            else
                msg = string.Format("My favorite day is {0:D}", FavoriteDay);

            MessageBox.Show(msg);
        }

#365 – SelectedDate and SelectedDates Properties of Calendar Control

The SelectedDate property of a Calendar control is a nullable DateTime (System.DateTime?) that represents a single selected date.

The SelectedDates property is an instance of SelectedDatesCollection, which is an ObservableCollection that contains DateTime values.  It represents the set of currently selected dates.

If the SelectionMode is None, or if no date is currently selected:

  • SelectedDate is null
  • SelectedDates is an empty collection

If SelectionMode is SingleDate and a date is selected:

  • SelectedDate contains a single DateTime value
  • SelectedDates contains a single DateTime element in the collection

If SelectionMode is SingleRange or MultipleRange and at least one date is selected:

  • SelectedDate contains a single DateTime value, equivalent to the first element in the SelectedDates collection
  • SelectedDates contains a DateTime element for each date that is currently selected

#364 – Allowing a User to Select Multiple Dates in a Calendar Control

By default, the Calendar control allows a user to select a single date.  You can set the SelectionMode property to allow the user to select more than one date.

SelectionMode (CalendarSelectionMode enumeration) can have one of the following values:

  • None – user can’t select date
  • SingleDate – select a single date  (default)

  • SingleRange – select a contiguous range of dates

  • MultipleRange – select multiple ranges of dates

If the SelectionMode is SingleDate, the SelectedDate property (DateTime) will contain the selected date.

If the SelectionMode is SingleRange or MultipleRange, the SelectedDates property (ObservableCollection of DateTime) will contain all of the selected dates.  The SelectedDate property will contain a copy of the first date in the SelectedDates collection.

#363 – Calendar Control Basics

The Calendar control displays an image of a calendar and allows a user to select a date.  By default, the calendar shows a single month that includes the current date.

    <StackPanel HorizontalAlignment="Center" Margin="15">
        <Calendar Name="cal"/>
        <Label Content="{Binding ElementName=cal, Path=SelectedDate, StringFormat=d}"/>
    </StackPanel>

When the user selects a date on the calendar, the SelectedDate property indicates the day that was selected.

You can use the left and right arrow icons at the top of the control to navigate to the previous/next month.

The Calendar control can also display a single year, or a single decade.  To switch to the Year mode, click on the name of the month at the top of the control.

You can now navigate to the previous/next year using the arrows, or click on a specific month.

You can switch to Decade mode by clicking on the year at the top of the control.