(Print this page)

Customizing the WPF Calendar control
Published date: Sunday, September 27, 2015
On: Moer and Éric Moreau's web site

Some controls are more complex than others in terms of features. The built-in Calendar control available to WPF application is one of them.

You can use its simple default version but you can also customize many of its element to better fit your needs and to give a better experience to your users.

Demo application

This month demo application has been created using Visual Studio 2015 but most of what is explained here is available in earlier version has well if you are at least using WPF 4.0.

The downloadable solution contains both VB and C#.

Figure 1: The demo application in action

Selection Mode

By default, you can select only one date in the control. But you can change that behavior by setting the SelectionMode property.

  • SingleDate: Default value. A single value can be selected. Use the SelectedDate property to get the value.
  • SingleRange: A single range of dates can be selected by the user. To select a range, click on the first date you want and then do Shift-Click to pick the second date. The Range will then be highlighted. Use the SelectedDates collection to find out the values.
  • MultipleRange: Let the user select range of dates contiguous or not. You can use the same click/Shift-Click to select a contiguous range and also Left-Ctrl-Click for discrete values. Use the SelectedDates collection to find out the values.
  • None: The calendar is effectively read-only. No dates may be selected. Clicking on a date changes the focus, but does not change the SelectedDate.

Blackout days

Sometime, you want to prevent your users to select some dates. This BlackoutDates collection is handling that.

If a date is already selected in the control and you try to set a black out on one of the selected date, you will get an ArgumentOutOfRange exception.

In my demo application, I catch this exception and set the selected date to nothing before setting the BlackoutDates range again.

Dim dtmStart As DateTime = New DateTime(Date.Today.Year, Date.Today.Month, 10)
Dim dtmEnd As DateTime = New DateTime(Date.Today.Year, Date.Today.Month, 15)
Try
    calendarControl.BlackoutDates.Add(New CalendarDateRange(dtmStart, dtmEnd))
Catch ex As ArgumentOutOfRangeException
    calendarControl.SelectedDate = Nothing
    calendarControl.BlackoutDates.Add(New CalendarDateRange(dtmStart, dtmEnd))
End Try

Min and Max days

If it is easier to set a range of allowed dates instead of blacking out all the invalid dates, you can set the DisplayDateStart and/or DisplayDateEnd to prevent user from being able to select outside the allowed range.

Dim dtmStart As DateTime = New DateTime(Date.Today.Year, Date.Today.Month, 10)
Dim dtmEnd As DateTime = New DateTime(Date.Today.Year, Date.Today.Month, 15)

If calendarControl.SelectionMode = CalendarSelectionMode.MultipleRange OrElse
    calendarControl.SelectionMode = CalendarSelectionMode.SingleRange Then
    calendarControl.SelectedDates.Clear()
    calendarControl.SelectedDate = dtmStart
Else
    If calendarControl.SelectedDate < dtmStart OrElse
        calendarControl.SelectedDate > dtmEnd Then
        calendarControl.SelectedDate = dtmStart
    End If
End If

calendarControl.DisplayDateStart = dtmStart
calendarControl.DisplayDateEnd = dtmEnd

Highlighting today’s date

It is sometimes useful to highlight today’s date but in other scenarios, it don’t make much sens.

It is very easy to toggle that behavior by setting the IsTodayHighlighted property:

calendarControl.IsTodayHighlighted = Not calendarControl.IsTodayHighlighted

There is more!

Many other properties/methods/events exist in the Calendar control class. You can view them all from the official MSDN documentation.

Conclusion

The calendar control might a complex control in terms of features but it is not too complex in terms of programming.

I have shown here how to customize the control through code because it is easier for demo purposes. All of the adjustments made here could also have been done through the XAML.


(Print this page)