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.