WPF Calendar


WPF has a nice built-in Calendar that looks like the one in Windows. It works along with the DatePicker control.

Calendar’s DisplayDate (of type DateTime) is initialized to the current date by default. Calendar ensures that the initial date is initially visible. There is an IsTodaysDateHighlighted property so that you can change the behaviour of having today’s date highlighted. The SelectionMode can change if one or more dates can be selected. SelectionMode has four possible values: SingleDate, SingleRange, MultipleRange and None.

Calendar has a FirstDayOfWeek so that you can change the first day displayed to any day other than the Sunday default. You can set it to any value of the System.DayOfWeek enumeration

Do you need to restrict the user to select only future dates? This would be a common requirement for setting appointments or contract dates of effective dates for example. In XAML you could use a CalendarDateRange with a Start value of DateTime.MinValue (which is January 1, 0001) and an end value of DateTime.Today minus 1 day.

An Example Adopted from Derek Banas

Below is a project that I made that was based on the YouTube video by Derek Banas called C# Tutorial 22 InkCanvas & Key Listeners. There are three controls in this project, not four as it seems to appear. The DatePicker control on the top right side of the screenshot has a popup calendar, which you see here. It appears only when the user clicks on the small calendar icon with the “15”. The DatePicker control is essentially a TextBox for displaying and entering a date along with a Calendarpopup for visually changing the date.

Here is the XAML.

<Window x:Class="Calendar2.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
        xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
        xmlns:local="clr-namespace:Calendar2"
        xmlns:sys="clr-namespace:System;assembly=mscorlib"
        mc:Ignorable="d"
        WindowStartupLocation="CenterScreen"
        Title="Calendar2" Height="350" Width="600">
    <Grid Background="#FFE5E5E5">
        <Calendar Name="MyCalendar" HorizontalAlignment="Left" Margin="17,40,0,0" 
                VerticalAlignment="Top" Background="AliceBlue" DisplayMode="Month"
                FirstDayOfWeek="Monday" IsTodayHighlighted="True"
                SelectedDatesChanged="MyCalendar_SelectedDatesChanged">
            <Calendar.BlackoutDates>
                <CalendarDateRange Start="4/2/2020" End="4/5/2020"/>
            </Calendar.BlackoutDates>
            <Calendar.SelectedDates>
                <sys:DateTime>4/25/2020</sys:DateTime>
            </Calendar.SelectedDates>
        </Calendar>
        <TextBox Name="tbDateSelected" HorizontalAlignment="Left" Height="23" Margin="17,17,0,0" 
                TextWrapping="Wrap" Text="TextBox" VerticalAlignment="Top" Width="120"/>
        <DatePicker Name="datePick" HorizontalAlignment="Left" Margin="252,40,0,0" 
                VerticalAlignment="Top"
                SelectedDateChanged="DatePick_SelectedDateChanged"/>
    </Grid>
</Window>

Here is the C# code behind. I added the MessageBox just for testing purposes.

using System;
using System.Windows;
using System.Windows.Controls;

namespace Calendar2
{
    public partial class MainWindow : Window
    {
        public MainWindow()
        {
            InitializeComponent();
        }
        private void DatePick_SelectedDateChanged(object sender, SelectionChangedEventArgs e)
        {
            DatePicker datePicker = sender as DatePicker;
            if (datePicker.SelectedDate.HasValue)
            {
                DateTime d = datePicker.SelectedDate.Value;
                MessageBox.Show("You picked " + d.ToLongDateString(), "InkCanvasDerekBanas");
            }
        }
        private void MyCalendar_SelectedDatesChanged(object sender, SelectionChangedEventArgs e)
        {
            var calendar = sender as Calendar;
            if (calendar.SelectedDate.HasValue)
            {
                {
                    DateTime d = calendar.SelectedDate.Value;
                    try
                    {
                        tbDateSelected.Text = d.ToShortDateString();
                    }
                    catch (NullReferenceException) { }

                }
            }
        }
    }
}