Plugin.Maui.Calendar 1.1.9

There is a newer version of this package available.
See the version list below for details.
dotnet add package Plugin.Maui.Calendar --version 1.1.9                
NuGet\Install-Package Plugin.Maui.Calendar -Version 1.1.9                
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="Plugin.Maui.Calendar" Version="1.1.9" />                
For projects that support PackageReference, copy this XML node into the project file to reference the package.
paket add Plugin.Maui.Calendar --version 1.1.9                
#r "nuget: Plugin.Maui.Calendar, 1.1.9"                
#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.
// Install Plugin.Maui.Calendar as a Cake Addin
#addin nuget:?package=Plugin.Maui.Calendar&version=1.1.9

// Install Plugin.Maui.Calendar as a Cake Tool
#tool nuget:?package=Plugin.Maui.Calendar&version=1.1.9                

Calendar Plugin for .NET MAUI

This is a .NET MAUI port of the lilcodelab Xamarin.Forms Calendar Plugin

Available on NuGet: https://www.nuget.org/packages/Plugin.Maui.Calendar NuGet

Simple cross platform plugin for Calendar control featuring:

  • Displaying events by binding EventCollection
  • Localization support with System.Globalization.CultureInfo
  • Customizable colors, day view sizes/label styles, custom Header/Footer template support
  • UI reactive to EventCollection, Culture and other changes

Screenshots

Android iPhone
Android Calendar Screenshot iPhone Calendar Screenshot
Win Mac
Windiws Calendar Screenshot Mac Calendar Screenshot

What's new

  • Removed all the platform-specific code hence it supports all available .NET MAUI backends: iOS, Android, Windows, Mac, Tizen (not tested yet)
  • Added Multiselection support (Latest PR that was not merged previously)
  • Exposed a few more properties for Arrow buttons customization
  • Refactored and revamped code
  • Updated to .NET 8
  • Added OnShownDateChangedCommand so we can take action when date is changed.
  • Added Dispose method to force handlers disconnect call.

Usage

To get started just install the package via Nuget. You can take a look on the sample app to get started or continue reading.

Reference the following xmlns to your page:

xmlns:controls="clr-namespace:Plugin.Maui.Calendar.Controls;assembly=Plugin.Maui.Calendar" 

Basic control usage:

<controls:Calendar
        Day="14"
        Month="5"
        Year="2019"
        VerticalOptions="Fill"
        HorizontalOptions="Fill">

Bindable properties:

  • Culture CultureInfo calender culture/language
  • Day int currently viewing day
  • Month int currently viewing month
  • Year int currently viewing year
  • Events EventCollection (from package) your events for calender
  • Custom colors, fonts, sizes ...

Remark: You can use ShownDate as an alternative to Year, Month and Day

<controls:Calendar
        ShownDate="2019-05-14"
        VerticalOptions="Fill"
        HorizontalOptions="Fill">
Binding events:

In your XAML, add the data template for events, and bind the events collection, example:

<controls:Calendar
    Events="{Binding Events}">
    <controls:Calendar.EventTemplate>
        <DataTemplate>
            <StackLayout
                Padding="15,0,0,0">
                <Label
                    Text="{Binding Name}"
                    FontAttributes="Bold"
                    FontSize="Medium" />
                <Label
                    Text="{Binding Description}"
                    FontSize="Small"
                    LineBreakMode="WordWrap" />
            </StackLayout>
        </DataTemplate>
    </controls:Calendar.EventTemplate>
</controls:Calendar>

In your ViewModel reference the following namespace:

using Plugin.Maui.Calendar.Models;

Add property for Events:

public EventCollection Events { get; set; }

Initialize Events with your data:

Events = new EventCollection
{
    [DateTime.Now] = new List<EventModel>
    {
        new EventModel { Name = "Cool event1", Description = "This is Cool event1's description!" },
        new EventModel { Name = "Cool event2", Description = "This is Cool event2's description!" }
    },
    // 5 days from today
    [DateTime.Now.AddDays(5)] = new List<EventModel>
    {
        new EventModel { Name = "Cool event3", Description = "This is Cool event3's description!" },
        new EventModel { Name = "Cool event4", Description = "This is Cool event4's description!" }
    },
    // 3 days ago
    [DateTime.Now.AddDays(-3)] = new List<EventModel>
    {
        new EventModel { Name = "Cool event5", Description = "This is Cool event5's description!" }
    },
    // custom date
    [new DateTime(2020, 3, 16))] = new List<EventModel>
    {
        new EventModel { Name = "Cool event6", Description = "This is Cool event6's description!" }
    }
};

Initialize Events with your data and a different dot color per day:

Events = new EventCollection
{
    //2 days ago
    [DateTime.Now.AddDays(-2)] = new DayEventCollection<EventModel>( Color.Purple, Color.Purple)
    {
        new EventModel { Name = "Cool event1", Description = "This is Cool event1's description!" },
        new EventModel { Name = "Cool event2", Description = "This is Cool event2's description!" }
    },
    // 5 days ago
    [DateTime.Now.AddDays(-5)] = new DayEventCollection<EventModel>(Color.Blue, Color.Blue)
    {
        new EventModel { Name = "Cool event3", Description = "This is Cool event3's description!" },
        new EventModel { Name = "Cool event4", Description = "This is Cool event4's description!" }
    },
};
//4 days ago
Events.Add(DateTime.Now.AddDays(-4), new DayEventCollection<EventModel>(GenerateEvents(10, "Cool")) { EventIndicatorColor = Color.Green, EventIndicatorSelectedColor = Color.Green });

Where EventModel is just an example, it can be replaced by any data model you desire.

EventsCollection is just a wrapper over Dictionary<DateTime, ICollection> exposing custom Add method and this[DateTime] indexer which internally extracts the .Date component of DateTime values and uses it as a key in this dictionary.

DayEventCollection is just a wrapper over List<T> exposing custom properties EventIndicatorColor and EventIndicatorSelectedColor for assigning a custom color to the dot.

Set up culture

In your ViewModel add property for Culture:

public CultureInfo Culture => new CultureInfo("hr-HR")

In XAML add Culture binding

<controls:Calendar
    Culture="{Binding Culture}">
</controls:Calendar>
Available color customization

Sample properties:

ArrowBorder
MonthLabelColor="Red"
YearLabelColor="Blue"
EventIndicatorColor="Red"
EventIndicatorSelectedColor="White"
DaysTitleColor="Orange"
DeselectedDayTextColor="Blue"
OtherMonthDayColor="Gray"
SelectedDayTextColor="Cyan"
SelectedDayBackgroundColor="DarkCyan"
SelectedDateColor="Red"
SelectedTodayTextColor="Green"
TodayOutlineColor="Blue"
TodayFillColor="Silver"
TodayTextColor="Yellow"
Available customization properties
Calendar Layout customizations

You can set the layout of the calendar with the property CalendarLayout

  • Available layouts are:

    OneWeek - only one week is shown

    TwoWeeks - two weeks are shown

    Month - the whole month is shown (default value)

CalendarLayout="Month"

You can also choose to display the shown week number instead of the month name

CalendarLayout="Week"
WeekViewUnit="WeekNumber"
Event indicator customizations

You can customize how the event indication will look with the property EventIndicatorType

  • Available indicators are: BottomDot - event indicator as dot bellow of date in the calendar (default value) TopDot - event indicator as the dot on top of the date in the calendar Background - event indicator as colored background in calendar BackgroundFull // event indicator as larger size colored background in the calendar
EventIndicatorType="Background"
Calendar swipe customizations

You can write your own customizations commands for swipe.

SwipeLeftCommand="{Binding SwipeLeftCommand}"
SwipeRightCommand="{Binding SwipeRightCommand}"
SwipeUpCommand="{Binding SwipeUpCommand}"

You can also disable default swipe actions.

SwipeToChangeMonthEnabled="False"
SwipeUpToHideEnabled="False"
Selection type of calendar

You can either use the Calender class implementation for a single selection mode, multiselection mode or RangeSelectionCalendar for a range selection mode.

    <plugin:Calendar
        SelectedDate="{Binding SelectedDate}"/>

On the RangeSelectionCalendar you can use binding for start date SelectedStartDate and end date SelectedEndDate or get list of selected dates with SelectedDates.

    <plugin:RangeSelectionCalendar
        x:Name="rangedCalendar"
        SelectedDates="{Binding SelectedDates}"
        SelectedEndDate="{Binding SelectedEndDate}"
        SelectedStartDate="{Binding SelectedStartDate}">

On the MultiselectionCalendar you can select multiple separate dates

    plugin:MultiSelectionCalendar
        Events="{Binding Events}"
        MaximumDate="{Binding MaximumDate}"
        MinimumDate="{Binding MinimumDate}"
        Month="{Binding Month}" >

Remark: Don't use both SelectedDates and SelectedStartDate/SelectedEndDate

Other customizations

Enable/Disable animation when calendar is loaded or refreshed Sample properties:

AnimateCalendar="False"

Enable/Disable the visibility of the Events scrollview panel at the bottom Sample properties:

EventsScrollViewVisible="True"
Section templates

There are several templates that can be used to customize the calendar. You can find an example for each one in the AdvancedPage.xaml. You can create your own custom control file or you can also write customization directly inside of Templates.

Calendar control sections

These sections provide customization over appearance of the controls of the calendar, like showing the selected month and year, month selection controls etc.

HeaderSectionTemplate

Customize the header section (top of the calendar control). Example from AdvancedPage.xaml

<plugin:Calendar.HeaderSectionTemplate>
    <controls:CalendarHeader />
</plugin:Calendar.HeaderSectionTemplate>
FooterSectionTemplate

Customize the footer section (under the calendar part, above the events list). Example from AdvancedPage.xaml

<plugin:Calendar.FooterSectionTemplate>
    <DataTemplate>
        <controls:CalendarFooter />
    </DataTemplate>
</plugin:Calendar.FooterSectionTemplate>
BottomSectionTemplate

Customize the bottom section (at the bottom of the calendar control, below the events list). Example from AdvancedPage.xaml

<plugin:Calendar.BottomSectionTemplate>
    <controls:CalendarBottom />
</plugin:Calendar.BottomSectionTemplate>
Event templates

These templates provide customization for the events list.

EventTemplate

Customize the appearance of the events section. Example from AdvancedPage.xaml

<plugin:Calendar.EventTemplate>
    <DataTemplate>
        <controls:CalenderEvent CalenderEventCommand="{Binding BindingContext.EventSelectedCommand, Source={x:Reference advancedCalendarPage}}" />
    </DataTemplate>
</plugin:Calendar.EventTemplate>
EmptyTemplate

Customize what to show in case the selected date has no events. Example from AdvancedPage.xaml

<plugin:Calendar.EmptyTemplate>
    <DataTemplate>
        <StackLayout>
            <Label Text="NO EVENTS FOR THE SELECTED DATE" HorizontalTextAlignment="Center" Margin="0,5,0,5" />
        </StackLayout>
    </DataTemplate>
</plugin:Calendar.EmptyTemplate>
Dispose

Due to issues with maui controls disposing (memory leaks) it is recomended to call Dispose() method on page Unload event (or similiar)

-Page Xaml-
Unloaded="UnloadedHandler"
-Code behind-
void UnloadedHandler(object sender, EventArgs e)
{
  calendar.Dispose();
}
Product Compatible and additional computed target framework versions.
.NET net8.0 is compatible.  net8.0-android was computed.  net8.0-android34.0 is compatible.  net8.0-browser was computed.  net8.0-ios was computed.  net8.0-ios17.2 is compatible.  net8.0-maccatalyst was computed.  net8.0-maccatalyst17.2 is compatible.  net8.0-macos was computed.  net8.0-tvos was computed.  net8.0-windows was computed.  net8.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.2.2 4,560 9/3/2024
1.2.1 3,031 8/6/2024
1.2.0 4,438 6/24/2024
1.1.9 472 6/19/2024
1.1.8 481 6/4/2024
1.1.7 2,294 5/17/2024
1.1.6 1,631 4/17/2024
1.1.5 220 4/16/2024
1.1.4 4,021 2/27/2024
1.1.3 167 2/26/2024
1.1.2 1,376 2/20/2024
1.1.1 1,495 1/5/2024
1.1.0 261 1/4/2024
1.0.11 145 1/3/2024
1.0.10 144 1/3/2024
1.0.9 155 1/2/2024
1.0.8 153 1/2/2024
1.0.7 190 12/28/2023
1.0.6 4,382 12/15/2023
1.0.5 604 11/27/2023
1.0.3 3,138 8/23/2023
1.0.2 193 8/22/2023
1.0.1 197 8/18/2023
1.0.0 267 8/17/2023

Add OnShownDateChangedCommand so we can take action when date is changed.
                           Update Maui packages.
                           Move MultiSelectionEngine to SelectionEnginesFolder.
                           RangeSelection not considering disabled dates.
                           Allow to programmatically clear selected day(s).
Fixed Calendar view is empty if we use it in a Shell Tab #63
Added Dispose method to force handler disconnect call;
Updated samples