Shaunebu.MAUI.CalendarControl 1.0.2

dotnet add package Shaunebu.MAUI.CalendarControl --version 1.0.2
                    
NuGet\Install-Package Shaunebu.MAUI.CalendarControl -Version 1.0.2
                    
This command is intended to be used within the Package Manager Console in Visual Studio, as it uses the NuGet module's version of Install-Package.
<PackageReference Include="Shaunebu.MAUI.CalendarControl" Version="1.0.2" />
                    
For projects that support PackageReference, copy this XML node into the project file to reference the package.
<PackageVersion Include="Shaunebu.MAUI.CalendarControl" Version="1.0.2" />
                    
Directory.Packages.props
<PackageReference Include="Shaunebu.MAUI.CalendarControl" />
                    
Project file
For projects that support Central Package Management (CPM), copy this XML node into the solution Directory.Packages.props file to version the package.
paket add Shaunebu.MAUI.CalendarControl --version 1.0.2
                    
#r "nuget: Shaunebu.MAUI.CalendarControl, 1.0.2"
                    
#r directive can be used in F# Interactive and Polyglot Notebooks. Copy this into the interactive tool or source code of the script to reference the package.
#:package Shaunebu.MAUI.CalendarControl@1.0.2
                    
#:package directive can be used in C# file-based apps starting in .NET 10 preview 4. Copy this into a .cs file before any lines of code to reference the package.
#addin nuget:?package=Shaunebu.MAUI.CalendarControl&version=1.0.2
                    
Install as a Cake Addin
#tool nuget:?package=Shaunebu.MAUI.CalendarControl&version=1.0.2
                    
Install as a Cake Tool

Shaunebu.MAUI.CalendarControl 📅

Platform MAUI License Status

NuGet Version

Android iOS macOS Windows

Support

Overview ✨

Shaunebu.MAUI.CalendarControl is a professional-grade, fully customizable calendar control for .NET MAUI with:

  • 4 view modes — Month, Year, Decade, and Century with drill-up/drill-down navigation
  • 4 selection modes — None, Single, Multiple, and Range
  • 50+ bindable properties — Full theming, styling, and behavioral customization
  • Full MVVM support — Commands for navigation, selection, view changes, and display date changes
  • Special dates — Custom backgrounds, text colors, indicator dots, and blackout dates
  • Swipe navigation — Left/right swipe gestures for month/year/decade/century navigation
  • Culture-aware — Localized month names, day names, and week numbering
  • AccessibilityAutomationProperties on all day cells with descriptive labels
  • Cross-platform — Android, iOS, macOS (Mac Catalyst), and Windows

Calendar Demo

Feature Highlights 🆚

Feature Description
Month View 6-row × 7-column day grid with optional week numbers and leading/trailing dates
Year View 3×4 grid of abbreviated month names with selection highlighting
Decade View 3×4 grid of 12 years (1 leading + 10 in-decade + 1 trailing)
Century View 3×4 grid of decade ranges with drill-down navigation
Single Selection Tap to select a single date; auto-navigates to tapped month
Multiple Selection Toggle dates on/off; ObservableCollection<DateTime> backed
Range Selection Two-tap range selection with visual range band
Blackout Dates Dates rendered with strikethrough and disabled interaction
Special Dates Per-date custom background, text color, indicator dot, and blackout flag
Min/Max Date Constrains navigation and disables out-of-range dates
Culture Support Fully localized via CultureInfo — month names, day names, week numbers
Header Date Format Customizable header format string (e.g., "MMM yyyy")
Day Name Format Full (Monday), Abbreviated (Mon), or Shortest (Mo)
Swipe Navigation Left/right swipe gestures on the body grid
Today Button Optional "Today" button for quick navigation to the current date
View Navigation Drill-up (header tap) and drill-down (cell tap) between view levels
MVVM Commands ForwardCommand, BackwardCommand, GoToTodayCommand, ResetSelectionCommand
Events + Commands SelectionChanged, ViewChanged, DisplayDateChanged with both events and bindable commands
Accessibility AutomationProperties.Name and HelpText on every day cell

Installation 📦

dotnet add package Shaunebu.MAUI.CalendarControl

Or via PackageReference:

<ItemGroup>
  <PackageReference Include="Shaunebu.MAUI.CalendarControl" Version="1.0.x" />
</ItemGroup>

Quick Start 🚀

1. Configure in MauiProgram.cs

using Shaunebu.MAUI.CalendarControl;

public static class MauiProgram
{
    public static MauiApp CreateMauiApp()
    {
        var builder = MauiApp.CreateBuilder();

        builder
            .UseMauiApp<App>()
            .UseShaunebuCalendar();

        return builder.Build();
    }
}

2. Add to XAML

<ContentPage xmlns="http://schemas.microsoft.com/dotnet/2021/maui"
             xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
             xmlns:cal="clr-namespace:Shaunebu.MAUI.CalendarControl;assembly=Shaunebu.MAUI.CalendarControl"
             x:Class="MyApp.MainPage">

    <cal:CalendarView
        SelectionMode="Single"
        ShowWeekNumbers="True"
        ShowTodayButton="True"
        FirstDayOfWeek="Monday"
        SelectionChanged="OnSelectionChanged" />

</ContentPage>

3. Handle Selection in Code-Behind

private void OnSelectionChanged(object sender, DateSelectionChangedEventArgs e)
{
    if (e.NewDate.HasValue)
    {
        DisplayAlert("Selected", e.NewDate.Value.ToShortDateString(), "OK");
    }
}

XAML Configuration Examples 🎨

Basic Calendar with Theming

<cal:CalendarView
    SelectionMode="Single"
    ShowWeekNumbers="True"
    ShowTodayButton="True"
    ShowNavigationArrows="True"
    FirstDayOfWeek="Monday"
    DayNameFormat="Abbreviated"
    HeaderBackground="#1976D2"
    HeaderTextColor="White"
    HeaderFontSize="20"
    DayTextColor="#333333"
    DayFontSize="14"
    TodayTextColor="#1976D2"
    TodayBorderColor="#1976D2"
    TodayBackground="Transparent"
    SelectionBackground="#1976D2"
    SelectionTextColor="White"
    WeekendTextColor="#999999"
    DayNamesTextColor="#888888"
    NavigationArrowColor="White"
    CellCornerRadius="20" />

Multiple Selection Mode

<cal:CalendarView
    x:Name="MultiCalendar"
    SelectionMode="Multiple"
    ShowLeadingAndTrailingDates="True" />
// Access selected dates
var dates = MultiCalendar.SelectedDates; // ObservableCollection<DateTime>

Range Selection Mode

<cal:CalendarView
    x:Name="RangeCalendar"
    SelectionMode="Range"
    RangeSelectionBackground="#331976D2" />
// Access selected range
var range = RangeCalendar.SelectedDateRange; // CalendarDateRange
if (range?.StartDate != null && range?.EndDate != null)
{
    // Use range.Contains(someDate) to check membership
}

Min/Max Date Constraints

<cal:CalendarView
    MinDate="{Binding MinimumDate}"
    MaxDate="{Binding MaximumDate}" />

Localized Calendar

<cal:CalendarView
    Culture="{Binding SelectedCulture}"
    HeaderDateFormat="MMMM yyyy"
    DayNameFormat="Shortest" />

MVVM Integration 🏗

Binding to Commands

<cal:CalendarView
    SelectionMode="Single"
    SelectedDate="{Binding SelectedDate, Mode=TwoWay}"
    DisplayDate="{Binding DisplayDate, Mode=TwoWay}"
    SelectionChangedCommand="{Binding DateSelectedCommand}"
    DisplayDateChangedCommand="{Binding MonthNavigatedCommand}"
    ViewChangedCommand="{Binding ViewDrilledCommand}"
    ForwardCommand="{Binding GoForwardCommand}"
    BackwardCommand="{Binding GoBackwardCommand}"
    GoToTodayCommand="{Binding NavigateToTodayCommand}"
    ResetSelectionCommand="{Binding ClearSelectionCommand}" />

ViewModel Example

public partial class CalendarViewModel : ObservableObject
{
    [ObservableProperty]
    private DateTime? selectedDate = DateTime.Today;

    [ObservableProperty]
    private DateTime displayDate = new(DateTime.Today.Year, DateTime.Today.Month, 1);

    [RelayCommand]
    private void DateSelected(DateSelectionChangedEventArgs e)
    {
        if (e.NewDate.HasValue)
        {
            // Handle date selection
            Debug.WriteLine($"Selected: {e.NewDate.Value:d}");
        }
    }

    [RelayCommand]
    private void MonthNavigated(DisplayDateChangedEventArgs e)
    {
        Debug.WriteLine($"Navigated from {e.OldDate:MMMM yyyy} to {e.NewDate:MMMM yyyy}");
    }
}

Special Dates & Blackout Dates 📌

Configure Special Dates

var calendar = new CalendarView();

// Add special dates with custom styling
calendar.SpecialDates.Add(new CalendarSpecialDate
{
    Date = new DateTime(2025, 12, 25),
    Background = Colors.Red,
    TextColor = Colors.White,
    IndicatorColor = Colors.Gold
});

// Add a blackout date via special dates
calendar.SpecialDates.Add(new CalendarSpecialDate
{
    Date = new DateTime(2025, 1, 1),
    IsBlackout = true
});

// Add blackout dates directly
calendar.BlackoutDates.Add(new DateTime(2025, 7, 4));
calendar.BlackoutDates.Add(new DateTime(2025, 11, 27));

Special Date Properties

Property Type Description
Date DateTime The date to customize
Background Color? Custom background color for the cell
TextColor Color? Custom text color for the day number
IndicatorColor Color? Color of a small dot indicator beneath the day number
IsBlackout bool If true, the date is disabled with strikethrough styling

Public Methods 🔧

Method Description
Forward() Navigate to the next month / year / decade / century
Backward() Navigate to the previous month / year / decade / century
GoToToday() Navigate to today's date and switch to Month view
GoToDate(DateTime date) Navigate to show the specified date in Month view
ResetSelection() Clear all selections across all modes

Bindable Properties Reference 📚

Selection Properties

Property Type Default Description
SelectedDate DateTime? DateTime.Today Selected date in Single mode
SelectedDates ObservableCollection<DateTime> Empty Selected dates in Multiple mode
SelectedDateRange CalendarDateRange? null Selected range in Range mode
SelectionMode CalendarSelectionMode Single None, Single, Multiple, or Range

Display & Navigation Properties

Property Type Default Description
DisplayDate DateTime First of current month Controls which month/year is displayed
View CalendarViewMode Month Current view mode
MinView CalendarViewMode Month Minimum drill-down level
MaxView CalendarViewMode Century Maximum drill-up level
MinDate DateTime? null Earliest navigable/selectable date
MaxDate DateTime? null Latest navigable/selectable date
FirstDayOfWeek DayOfWeek Culture default First day of the week
AllowViewNavigation bool true Enable header tap drill-up and cell drill-down

Visibility Properties

Property Type Default Description
ShowLeadingAndTrailingDates bool true Show dates from adjacent months
ShowWeekNumbers bool false Show ISO week numbers column
ShowTodayButton bool false Show "Today" button below calendar
ShowNavigationArrows bool true Show forward/backward arrow buttons

Formatting Properties

Property Type Default Description
Culture CultureInfo CurrentCulture Culture for localized formatting
HeaderDateFormat string? null (= "MMMM yyyy") Custom header date format string
DayNameFormat CalendarDayNameFormat Abbreviated Day name display format

Styling Properties

Property Type Default Description
HeaderBackground Color Transparent Header row background
HeaderTextColor Color #333333 Header label text color
HeaderFontSize double 18.0 Header label font size
DayTextColor Color #333333 Default day number text color
DayFontSize double 14.0 Day number font size
TodayBackground Color Transparent Today cell background
TodayTextColor Color #1976D2 Today cell text color
TodayBorderColor Color #1976D2 Today cell border ring color
SelectionBackground Color #1976D2 Selected cell background
SelectionTextColor Color White Selected cell text color
RangeSelectionBackground Color #331976D2 Range band background
WeekendTextColor Color #999999 Weekend day text color
TrailingLeadingTextColor Color #CCCCCC Adjacent month day text color
DisabledTextColor Color #DDDDDD Disabled/out-of-range text color
DayNamesTextColor Color #888888 Day-of-week header text color
DayNamesFontSize double 12.0 Day-of-week header font size
WeekNumberTextColor Color #AAAAAA Week number text color
WeekNumberBackground Color Transparent Week number column background
NavigationArrowColor Color #333333 Navigation arrow button color
CellCornerRadius double 20 Corner radius for selected/today cells

Command Properties (MVVM)

Property Type Description
SelectionChangedCommand ICommand Invoked when selection changes
SelectionChangedCommandParameter object Parameter for SelectionChangedCommand
ViewChangedCommand ICommand Invoked when view mode changes
ViewChangedCommandParameter object Parameter for ViewChangedCommand
DisplayDateChangedCommand ICommand Invoked when display date changes
DisplayDateChangedCommandParameter object Parameter for DisplayDateChangedCommand
ForwardCommand ICommand Navigate forward command
BackwardCommand ICommand Navigate backward command
GoToTodayCommand ICommand Go to today command
ResetSelectionCommand ICommand Reset selection command

Events 📡

Event EventArgs Description
SelectionChanged DateSelectionChangedEventArgs Raised when user changes selection
ViewChanged CalendarViewChangedEventArgs Raised when the view mode changes
DisplayDateChanged DisplayDateChangedEventArgs Raised when navigating to a different month/year

DateSelectionChangedEventArgs

Property Type Description
NewDate DateTime? Newly selected date (Single mode)
OldDate DateTime? Previously selected date (Single mode)
AddedDates IReadOnlyList<DateTime>? Dates added (Multiple mode)
RemovedDates IReadOnlyList<DateTime>? Dates removed (Multiple mode)
NewRange CalendarDateRange? New range (Range mode)
OldRange CalendarDateRange? Previous range (Range mode)

Architecture Overview 🏗

┌────────────────────────────────────────────────────────────────────┐
│              Shaunebu.MAUI.CalendarControl                         │
├────────────────────────────────────────────────────────────────────┤
│ Controls/                                                          │
│   CalendarView.cs          Main ContentView control (~1500 lines)  │
│     ├─ Bindable Properties   50+ configurable properties           │
│     ├─ Rendering Engine      Month / Year / Decade / Century views │
│     ├─ Selection Handling    Single / Multiple / Range / None      │
│     ├─ Navigation            Forward / Backward / DrillUp / Down   │
│     ├─ MVVM Commands         8 bindable ICommand properties        │
│     └─ Accessibility         AutomationProperties on all cells     │
├────────────────────────────────────────────────────────────────────┤
│ Enums/                                                             │
│   CalendarViewMode.cs       Month | Year | Decade | Century        │
│   CalendarSelectionMode.cs  None | Single | Multiple | Range       │
│   CalendarDayNameFormat.cs  Full | Abbreviated | Shortest          │
├────────────────────────────────────────────────────────────────────┤
│ Models/                                                            │
│   CalendarDateRange.cs      Start/End date range with Contains()   │
│   CalendarSpecialDate.cs    Per-date visual customization model    │
├────────────────────────────────────────────────────────────────────┤
│ Events/                                                            │
│   DateSelectionChangedEventArgs.cs    Multi-mode selection args    │
│   CalendarViewChangedEventArgs.cs     View mode change args        │
│   DisplayDateChangedEventArgs.cs      Display date change args     │
├────────────────────────────────────────────────────────────────────┤
│ Extensions/                                                        │
│   AppBuilderExtensions.cs   UseShaunebuCalendar() registration     │
├────────────────────────────────────────────────────────────────────┤
│ Platforms/                                                         │
│   Android/   iOS/   MacCatalyst/   Windows/                        │
└────────────────────────────────────────────────────────────────────┘

Advanced Usage Scenarios 🔥

Booking / Scheduling Calendar

var calendar = new CalendarView
{
    SelectionMode = CalendarSelectionMode.Range,
    MinDate = DateTime.Today,
    MaxDate = DateTime.Today.AddMonths(6),
    ShowTodayButton = true
};

// Block out unavailable dates
foreach (var bookedDate in existingBookings)
    calendar.BlackoutDates.Add(bookedDate);

// Highlight available premium slots
foreach (var slot in premiumSlots)
{
    calendar.SpecialDates.Add(new CalendarSpecialDate
    {
        Date = slot,
        IndicatorColor = Colors.Gold,
        Background = Color.FromArgb("#FFF8E1")
    });
}

Multi-Tenant Event Calendar

// Mark event dates with color-coded indicators
calendar.SpecialDates.Add(new CalendarSpecialDate
{
    Date = meetingDate,
    IndicatorColor = Colors.Blue
});

calendar.SpecialDates.Add(new CalendarSpecialDate
{
    Date = deadlineDate,
    IndicatorColor = Colors.Red,
    TextColor = Colors.Red
});

calendar.SpecialDates.Add(new CalendarSpecialDate
{
    Date = holidayDate,
    IsBlackout = true
});

Culture-Aware International Calendar

var calendar = new CalendarView
{
    Culture = new CultureInfo("ar-SA"),        // Arabic (Saudi Arabia)
    FirstDayOfWeek = DayOfWeek.Saturday,
    DayNameFormat = CalendarDayNameFormat.Shortest,
    HeaderDateFormat = "MMMM yyyy"
};

Programmatic Navigation

// Navigate to a specific date
calendar.GoToDate(new DateTime(2025, 12, 25));

// Navigate forward/backward
calendar.Forward();
calendar.Backward();

// Jump to today
calendar.GoToToday();

// Clear all selections
calendar.ResetSelection();

Supported Platforms 📱

Platform Minimum Version Target Frameworks
Android API 21 (Lollipop) net9.0-android, net10.0-android
iOS 15.0 net9.0-ios, net10.0-ios
macOS Mac Catalyst 15.0 net9.0-maccatalyst, net10.0-maccatalyst
Windows 10.0.17763.0 net9.0-windows10.0.19041.0, net10.0-windows10.0.19041.0

Troubleshooting 🔧

Calendar Not Rendering

  • Ensure UseShaunebuCalendar() is called in MauiProgram.cs
  • Verify the XAML namespace: xmlns:cal="clr-namespace:Shaunebu.MAUI.CalendarControl;assembly=Shaunebu.MAUI.CalendarControl"

Selection Not Working

  • Check that SelectionMode is not set to None
  • Verify the date is not in BlackoutDates or SpecialDates with IsBlackout = true
  • Ensure the date is within MinDate / MaxDate bounds
  • The arrows automatically disable when MinDate / MaxDate boundaries are reached
  • Verify ShowNavigationArrows is true

View Drill-Up/Down Not Working

  • Set AllowViewNavigation="True" (default)
  • The header label must be tapped to drill up
  • View navigation respects MinView and MaxView bounds

Week Numbers Not Showing

  • Set ShowWeekNumbers="True"
  • Week numbers use the Culture property's calendar week rule

License 📄

This project is licensed under the MIT License.

Product Compatible and additional computed target framework versions.
.NET net9.0 is compatible.  net9.0-android was computed.  net9.0-android35.0 is compatible.  net9.0-browser was computed.  net9.0-ios was computed.  net9.0-ios18.0 is compatible.  net9.0-maccatalyst was computed.  net9.0-maccatalyst18.0 is compatible.  net9.0-macos was computed.  net9.0-tvos was computed.  net9.0-windows was computed.  net9.0-windows10.0.19041 is compatible.  net10.0 is compatible.  net10.0-android was computed.  net10.0-android36.0 is compatible.  net10.0-browser was computed.  net10.0-ios was computed.  net10.0-ios26.0 is compatible.  net10.0-maccatalyst was computed.  net10.0-maccatalyst26.0 is compatible.  net10.0-macos was computed.  net10.0-tvos was computed.  net10.0-windows was computed.  net10.0-windows10.0.19041 is compatible. 
Compatible target framework(s)
Included target framework(s) (in package)
Learn more about Target Frameworks and .NET Standard.

NuGet packages

This package is not used by any NuGet packages.

GitHub repositories

This package is not used by any popular GitHub repositories.

Version Downloads Last Updated
1.0.2 116 4/8/2026
1.0.1 116 4/8/2026
1.0.0 109 4/8/2026