Highlighting dates in UWP CalendarView

I have posted about UWP CalendarView control a while back. The previous post summarized how to customize calendar days while they are being assigned. A new StackOverflow question has prompted me to revisit this to show how already displayed dates can be adjusted as well.

Setting the scene

Consider the following simple XAML markup:

<StackPanel Padding="20" Spacing="20">
<DatePicker x:Name="Picker" />
<Button Click="Add_Click">Add</Button>
<CalendarView CalendarViewDayItemChanging="Calendar_CalendarViewDayItemChanging" x:Name="Calendar" />
</StackPanel>

view raw
CalendarPicker.xaml
hosted with ❤ by GitHub

What we will want to do is to let the user pick dates via the DatePicker and highlight them in the CalendarView.

Date highlighting

First will keep the selected dates in a collection of DateTimeOffset instances in the code-behind:

private List<DateTimeOffset> _highlightedDates = new List<DateTimeOffset>();

view raw
HighlightedDates.cs
hosted with ❤ by GitHub

When the user clicks the add button, we execute the following:

private void Add_Click(object sender, RoutedEventArgs e)
{
_highlightedDates.Add(Picker.Date.Date);
UpdateCalendar();
}

view raw
AddHandler.cs
hosted with ❤ by GitHub

The key logic will be in the UpdateCalendar method. This must enumerate all the currently displayed dates and ensure the ones which the user selected are highlighted. Unfortunately, CalendarView does not provide a friendly “Dates” or “Items” property so to get the individual CalendarViewDayItem instances, we will have to use VisualTreeHelper to crawl the visual tree of the calendar control and find all controls of given type. While the implementation is not that complex, its even better to avoid reinventing the wheel and just use the FindDescendants<T> extension method from Windows Community Toolkit!

First – install the Microsoft.Toolkit.Uwp.UI from NuGet:

Adding Toolkit NuGet

Once installed, add the following using declaration to the top of your code-behind:

using Microsoft.Toolkit.Uwp.UI.Extensions;

view raw
Extensions.cs
hosted with ❤ by GitHub

And now let’s use it!

private void UpdateCalendar()
{
var displayedDays = Calendar.FindDescendants<CalendarViewDayItem>();
foreach (var displayedDay in displayedDays)
{
if (_highlightedDates.Contains(displayedDay.Date.Date))
{
HighlightDay(displayedDay);
}
else
{
UnHighlightDay(displayedDay);
}
}
}

view raw
UpdateCalendar.cs
hosted with ❤ by GitHub

We find all CalendarViewDayItem children of CalendarView, enumerate them and then check if the date matches one of the user selections. If yes, we highlight it. Conversely, we unhighlight (that is because the CalendarViewDayItem instances are reused, so we have to make sure their state is always set properly).

The highlight methods are very simple:

private static void HighlightDay(CalendarViewDayItem displayedDay)
{
displayedDay.Background = new SolidColorBrush(Colors.Red);
}
private static void UnHighlightDay(CalendarViewDayItem displayedDay)
{
displayedDay.Background = new SolidColorBrush(Colors.Transparent);
}

view raw
HighlightDay.cs
hosted with ❤ by GitHub

Finally, we apply the knowledge from the previous blog post and handle the CalendarViewDayItemChanging event:

private void Calendar_CalendarViewDayItemChanging(CalendarView sender, CalendarViewDayItemChangingEventArgs args)
{
if (_highlightedDates.Contains(args.Item.Date))
{
HighlightDay(args.Item);
}
else
{
UnHighlightDay(args.Item);
}
}

This is essentially the same thing logic as in UpdateCalendar, but here we are directly given a specific CalendarViewDayItem to work with.

Sample code

The example project is available on my GitHub.

CalendarView highlighting
CalendarView highlighting
Buy me a coffeeBuy me a coffee

1 thought on “Highlighting dates in UWP CalendarView”

Leave a Reply

Your email address will not be published. Required fields are marked *

You may use these HTML tags and attributes: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <s> <strike> <strong>

*

This site uses Akismet to reduce spam. Learn how your comment data is processed.