Scheduler | Custom Templates
All scheduler views support custom DataTemplate properties to override the default visual elements. Templates must use AOT-safe static lambda bindings — never string-based SetBinding().
Built-in Default Templates
Section titled “Built-in Default Templates”The DefaultTemplates static class provides reusable template factories:
| Method | Binds To | Description |
|---|---|---|
CreateEventItemTemplate() | SchedulerEvent | Color bar + title label |
CreateOverflowTemplate() | CalendarOverflowContext | ”+N more” overflow label |
CreateLoaderTemplate() | None | ActivityIndicator + “Loading…” |
CreateCalendarListDayHeaderTemplate() | CalendarListDayGroup | Accent bar + today dot + bold date + event count |
CreateCalendarListEventItemTemplate() | SchedulerEvent | Card with color bar, title, description, time range |
CreateAppleCalendarDayPickerTemplate() | DatePickerItemContext | Apple Calendar-style day picker (default for Agenda) |
Template Binding Contexts
Section titled “Template Binding Contexts”SchedulerEvent
Section titled “SchedulerEvent”Used by EventItemTemplate on all views:
public class SchedulerEvent{ public string Identifier { get; set; } public string Title { get; set; } public string? Description { get; set; } public Color? Color { get; set; } public bool IsAllDay { get; set; } public DateTimeOffset Start { get; set; } public DateTimeOffset End { get; set; }}CalendarListDayGroup
Section titled “CalendarListDayGroup”Used by DayHeaderTemplate on SchedulerCalendarListView:
public class CalendarListDayGroup : List<SchedulerEvent>{ public DateOnly Date { get; } public string DateDisplay { get; } // "dddd, MMMM d, yyyy" public bool IsToday { get; } public string EventCountDisplay { get; } // "3 events"}DatePickerItemContext
Section titled “DatePickerItemContext”Used by DayPickerItemTemplate on SchedulerAgendaView:
public class DatePickerItemContext{ public DateOnly Date { get; set; } public string DayNumber { get; set; } // "30" public string DayName { get; set; } // "MON" public string MonthName { get; set; } // "MAR" public bool IsSelected { get; set; } public bool IsToday { get; set; }}CalendarOverflowContext
Section titled “CalendarOverflowContext”Used by OverflowItemTemplate on SchedulerCalendarView:
public class CalendarOverflowContext{ public int EventCount { get; set; } public DateOnly Date { get; set; }}Writing Custom Templates
Section titled “Writing Custom Templates”AOT-Safe Bindings
Section titled “AOT-Safe Bindings”Always use the static lambda overload of SetBinding():
// Correct — AOT safelabel.SetBinding(Label.TextProperty, static (SchedulerEvent e) => e.Title);
// WRONG — not AOT safe, will fail in trimmed/AOT buildslabel.SetBinding(Label.TextProperty, "Title");Example: Custom Event Template
Section titled “Example: Custom Event Template”var template = new DataTemplate(() =>{ var grid = new Grid { ColumnDefinitions = { new ColumnDefinition(new GridLength(4)), new ColumnDefinition(GridLength.Star) }, Padding = new Thickness(8), ColumnSpacing = 8 };
var colorBar = new BoxView { CornerRadius = 2 }; colorBar.SetBinding(BoxView.ColorProperty, static (SchedulerEvent e) => e.Color);
var stack = new VerticalStackLayout { Spacing = 2 };
var title = new Label { FontSize = 14, FontAttributes = FontAttributes.Bold }; title.SetBinding(Label.TextProperty, static (SchedulerEvent e) => e.Title);
var description = new Label { FontSize = 12, TextColor = Colors.Gray }; description.SetBinding(Label.TextProperty, static (SchedulerEvent e) => e.Description);
stack.Children.Add(title); stack.Children.Add(description);
grid.Add(colorBar, 0); grid.Add(stack, 1); return grid;});Example: Custom Day Picker Template
Section titled “Example: Custom Day Picker Template”var template = new DataTemplate(() =>{ var stack = new VerticalStackLayout { Spacing = 2, Padding = new Thickness(8, 4), HorizontalOptions = LayoutOptions.Center };
var dayName = new Label { FontSize = 10, HorizontalTextAlignment = TextAlignment.Center, TextColor = Colors.Gray }; dayName.SetBinding(Label.TextProperty, static (DatePickerItemContext c) => c.DayName);
var dayNumber = new Label { FontSize = 18, FontAttributes = FontAttributes.Bold, HorizontalTextAlignment = TextAlignment.Center }; dayNumber.SetBinding(Label.TextProperty, static (DatePickerItemContext c) => c.DayNumber);
stack.Children.Add(dayName); stack.Children.Add(dayNumber); return stack;});Example: Custom Loader Template
Section titled “Example: Custom Loader Template”var template = new DataTemplate(() =>{ var stack = new VerticalStackLayout { VerticalOptions = LayoutOptions.Center, HorizontalOptions = LayoutOptions.Center, Spacing = 8 };
stack.Children.Add(new ActivityIndicator { IsRunning = true, Color = Colors.DodgerBlue }); stack.Children.Add(new Label { Text = "Fetching events...", TextColor = Colors.Gray });
return stack;});Template Properties Per View
Section titled “Template Properties Per View”| View | Template Properties |
|---|---|
SchedulerCalendarView | EventItemTemplate, OverflowItemTemplate, LoaderTemplate |
SchedulerAgendaView | EventItemTemplate, DayPickerItemTemplate, LoaderTemplate |
SchedulerCalendarListView | EventItemTemplate, DayHeaderTemplate, LoaderTemplate |