
Syncfusion Blazor Scheduler
- 248 installs
- 4 repo stars
- Updated July 28, 2026
- syncfusion/blazor-ui-components-skills
Use syncfusion-blazor-scheduler for development tasks
About
syncfusion-blazor-scheduler: A skill for development. This provides functionality for development workflows.
- syncfusion-blazor-scheduler
Syncfusion Blazor Scheduler by the numbers
- 248 all-time installs (skills.sh)
- +14 installs in the week ending Aug 5, 2026 (Skillselion tracking)
- Ranked #1,549 of 4,347 Backend & APIs skills by installs in the Skillselion catalog
- Data as of Aug 5, 2026 (Skillselion catalog sync)
npx skills add https://github.com/syncfusion/blazor-ui-components-skills --skill syncfusion-blazor-schedulerAdd your badge
Show developers this skill is listed on Skillselion. Paste this into your README.
| Installs | 248 |
|---|---|
| repo stars | ★ 4 |
| Last updated | July 28, 2026 |
| Repository | syncfusion/blazor-ui-components-skills ↗ |
What it does
Use syncfusion-blazor-scheduler for development tasks
Files
Syncfusion Blazor Scheduler Component
When to Use This Skill
Use this skill whenever the user needs to:
- Create or configure a Blazor Scheduler component
- Bind local or remote data
- Manage appointments, events, or calendar data
- Set up different calendar views (Day, Week, Month, Timeline, Agenda)
- Implement recurring events or recurrence patterns
- Handle appointment CRUD operations (create, read, update, delete)
- Configure appointment drag-and-drop or resizing
- Work with resources or grouping
- Set up timezones or localization
- Customize Scheduler appearance or behavior
- Handle events and callbacks
- Persist state or manage data binding
- Enable accessibility features
- Export or print scheduler data
- Set up virtual scrolling for large datasets
- Use clipboard copy, cut, or Paste features
- Configure custom toolbar
Component Overview
The Syncfusion Blazor Scheduler is a comprehensive calendar component that allows you to:
- Display appointments in multiple views (Day, Week, Month, Timeline, Agenda, Year)
- Manage appointments with full CRUD operations and complete control
- Support recurring events with iCalendar-compatible recurrence rules
- Enable drag-and-drop and resizing functionality for intuitive scheduling
- Handle multiple resources and flexible grouping models
- Support timezone-aware appointments with IANA timezone conversion
- Customize appointment appearance with templates, EventRendered events, and CSS classes
- Prevent or customize overlapping appointments (AllowOverlap property)
- Configure blocking time slots and read-only appointments
- Display interactive tooltips with custom templates
- Persist state and manage local/remote data binding
- Filter, retrieve, and refresh appointments dynamically
- Provide keyboard navigation, accessibility (WCAG 2.2), and RTL support
Documentation and Navigation Guide
Getting Started
📄 Read: references/getting-started.md
- Installation via NuGet packages
- Setting up Blazor project
- Adding required namespaces and services
- Basic component initialization
- First minimal working example
Appointments and Event Fields
📄 Read: references/appointments.md
- Built-in appointment fields (Id, Subject, StartTime, EndTime, Location, Description, Timezone, etc.)
- Custom field mapping, binding, and validation
- Event field settings with labels, defaults, and validation rules
- Adding custom fields to appointments
- Normal, spanned, all-day, and blocked events
- Read-only appointments and slot availability
- Overlapping event customization and prevention (AllowOverlap)
- Appointment appearance with EventRendered styling
- Tooltips (built-in, custom templates, conditional)
- Appointment selection and retrieval (GetEventsAsync, GetCurrentViewEvents)
- Filtering appointments with Query
- Refresh appointments with RefreshEventsAsync
Appointment Customization
📄 Read: references/appointment-customization.md
- Template-based event customization
- EventRendered event for styling
- CssClass property for bulk styling
- Custom attributes and classes
- Event appearance modifications
Drag and Drop
📄 Read: references/appointment-drag-and-drop.md
- Enable/disable drag-and-drop functionality
- Single and multi-drag operations
- Drag event handling and prevention
- Scroll control during drag
- Navigation trigger on edges
- Drag intervals and external sources
- Opening editor on drag completion
Resizing Events
📄 Read: references/appointment-resizing.md
- Enable/disable resizing functionality
- Scroll control during resize
- Scroll speed configuration
- Resize time intervals
- Preventing specific resizing actions
Scheduler Views
📄 Read: references/views.md
- 12 available view modes (Day, Week, WorkWeek, Month, Agenda, MonthAgenda, TimelineDay, TimelineWeek, TimelineWorkWeek, TimelineMonth, TimelineYear, Year)
- Setting current/active view with @bind-CurrentView property
- View-specific configuration properties table
- ScheduleView component properties (Option, IsSelected, DateFormat, Readonly, ShowWeekend, WorkDays, etc.)
- Day view with hourly time slots and single-day display
- Day view with Interval property for multiple consecutive days (2-day, 3-day views)
- Week view displaying 7-day week (Sunday-Saturday) with all appointments
- Week view with FirstDayOfWeek customization (1=Monday, 0=Sunday)
- Work Week view showing only working days (Mon-Fri by default)
- Custom working days per view with WorkDays int array (0=Sun, 1=Mon, etc.)
- Month view with full month calendar grid layout
- Month view with MaxEventsPerRow property to limit/expand events display
- Agenda view displaying upcoming events in chronological list format (7 days default)
- Agenda view with AgendaDaysCount property for custom date range
- Agenda view with AllowVirtualScrolling for large datasets
- Month Agenda view combining month calendar with agenda list below
- Timeline Day view showing single day in horizontal layout
- Timeline Week view showing 7-day week horizontally
- Timeline Work Week view showing working days horizontally
- Timeline Month view showing entire month horizontally
- Timeline Year view showing full year horizontally with Orientation customization
- Year view displaying mini-calendar with month selection and appointment indicators
- Extending view intervals with Interval property (3-day, 2-week, quarterly, annual views)
- Display Name customization for extended views with DisplayName property
- Setting specific start and end hours with StartHour/EndHour (e.g., "09:00"-"18:00")
- Time range limiting to business hours only
- Hide weekends in calendar views using ShowWeekend="false"
- Display ISO week numbers with ShowWeekNumber="true"
- Readonly mode per view using Readonly="true" to prevent CRUD operations
- View-specific templates (EventTemplate, DateHeaderTemplate, CellTemplate, etc.)
- Event template customization per view for different rendering
- Date header template customization per view
- Cell templates and custom cell content per view
- DateFormat customization per view for date display
- Switching views programmatically with CurrentView property binding
- View navigation via header toolbar with built-in view buttons
- Resource header templates per view for grouped schedules
- Resource-based view configuration and display options
Events and Interactions
📄 Read: references/events.md
- All Scheduler events (ActionBegin, ActionCompleted, Created, Destroyed, etc.)
- Event arguments and action types
- Two-way binding and callbacks
- DataBinding and DataBound events
- Event selection and retrieval
Recurring Events
📄 Read: references/recurring-events.md
- Recurrence rule syntax and iCalendar format
- FREQ, INTERVAL, COUNT, UNTIL properties
- BYDAY, BYMONTHDAY, BYMONTH configurations
- Creating recurring events
- Exception dates and editing occurrences
- Edit/delete following events
CRUD Operations
📄 Read: references/crud-actions.md
- Create appointments via editor or AddEventAsync
- Inline appointment creation
- Update appointments with proper validation
- Delete single or multiple appointments
- Server-side database operations
- Restricting actions based on criteria
Data Binding
📄 Read: references/data-binding.md
- Local data binding with List collections
- Remote data binding with HTTP services
- DataSource configuration
- Query-based filtering
- Refresh appointments dynamically
- DataSource property and event settings
- Load data on demand
- Set custom headers for authentication/authorization
Customization and Styling
📄 Read: references/scheduler-styling.md
- CSS customization and theming
- Custom styling with CssClass
- Style overrides for components
- Color schemes and themes
- Responsive design adjustments
Cell Customization
📄 Read: references/cell-customization.md
- Cell dimensions in vertical and timeline views
- CellTemplate for custom content
- CellHeaderTemplate for headers
- OnRenderCell event for dynamic styling
- Weekend and specific date styling
- MinDate and MaxDate restrictions
- Multi-cell and multi-row selection
Header Bar and Toolbar Customization
📄 Read: references/header-bar.md
- ShowHeaderBar property to display or hide header
- ScheduleToolBar component for toolbar configuration
- Built-in toolbar items (ScheduleToolBarPrevious, Next, DateRange, Today, Views, NewEvent)
- ScheduleToolBarCustom for adding custom elements to toolbar
- ItemType options for custom items (Button, Input, Spacer, Separator)
- Creating custom toolbar with buttons for export, print, and other actions
- Adding dropdown controls to toolbar for filtering by resources
- Real-world toolbar configuration example with owner resource filtering
- EnableAdaptiveUI property for responsive/mobile-friendly layout
- Toolbar consolidation and "New Event" button in adaptive mode
- DateHeaderTemplate for customizing date cells in day/week views
- OnRenderCell event with ElementType.DateHeader for dynamic date header styling
- Weekend and special date styling in date header
- DateRangeTemplate for customizing displayed date range text
- TimelineYear view header customization with DayHeaderTemplate
- MonthHeaderTemplate for month headers in TimelineYear
- HeaderIndentTemplate for customizing left indent area in timeline views
- Vertical and horizontal orientation in timeline views
- Resource-grouped view headers
- Combining multiple templates for advanced header layouts
Header Rows
📄 Read: references/header-rows.md
- ScheduleHeaderRow component structure and properties
- HeaderRowType enum options (Year, Month, Week, Date, Hour)
- View compatibility for each header row type
- Basic multi-level header row setup
- Year and month header rows for long-range timelines
- Week number header rows for weekly organization
- Displaying complete year timeline with Interval=12
- Day and hour header rows for detailed scheduling
- Customizing header rows with Template property
- Template context and accessing Date in templates
- Header row styling with CSS classes
- Color customization for different header levels
- Header rows with resource-grouped views
- Combining multiple header rows (2-5 levels)
- Order and hierarchy guidelines for header rows
- Localization in header rows by culture
- ISO week number calculations and display
- Common patterns (quarterly, weekly, daily, resource views)
- Performance considerations with multiple rows
Editor Template
📄 Read: references/editor-template.md
- Default editor window and double-click behavior
- Customizing editor field labels with Title property
- Field validation using ValidationRules (Required, RegexPattern, MinLength, MaxLength)
- Editing default time duration with OnPopupOpen event
- Preventing editor/quick popups by canceling PopupOpenEventArgs
- Popup types (Editor, QuickInfo, EditEventInfo, ViewEventInfo, EventContainer, etc.)
- Opening editor window manually with OpenEditorAsync method
- Creating completely custom editor using EditorTemplate
- Customizing editor header and footer with EditorHeaderTemplate/EditorFooterTemplate
- Adding resource dropdown options to editor template
- Adding recurrence pattern fields to editor template
- Applying DataAnnotations validation in editor templates
- Quick info popups on single-click (cell and event)
- Customizing quick popup appearance with ScheduleQuickInfoTemplates
- Quick popup template types (Cell, Event, Both) for different popup scenarios
- Custom header, content, footer for quick popups
- Disabling quick popups with ShowQuickInfo or OnPopupOpen event
- Multiple cell selection and QuickInfoOnSelectionEnd property
- AllowMultiRowSelection for multi-day selection behavior
- More events indicator popup when cell exceeds capacity
- Preventing more events popup with MoreEventsClicked event
- CloseQuickInfoPopupAsync method to programmatically close popups
Clipboard Operations
📄 Read: references/clipboard.md
- Copy/paste appointments
- Copy event data to clipboard
- Paste handling and validation
- Multi-appointment operations
Resources and Grouping
📄 Read: references/resources.md
- ScheduleResource component structure and generic parameters
- Resource field mapping (Field, TextField, IdField, ColorField, etc.)
- Complete resource fields reference table
- Local resource data binding with List collections
- Binding resources with ExpandoObject for dynamic models
- Binding resources with DynamicObject custom implementation
- Binding resources with ObservableCollection for dynamic updates
- Multiple resources without visual grouping (AllowMultiple property)
- Single-level resource grouping with ScheduleGroup
- Multi-level hierarchical resource grouping (GroupIDField)
- One-to-One grouping with ByGroupID="false"
- Grouping resources by date (ByDate="true") in calendar views
- Shared events across resources (AllowGroupEdit="true")
- Simple resource header customization with templates
- Multiple column resource headers for timeline views
- Expand and collapse resources with ExpandedField
- Resource header tooltips with HeaderTooltipTemplate
- Resource color selection with ResourceColorField
- Custom working hours per resource (StartHourField, EndHourField)
- Custom working days per resource (WorkDaysField)
Timescale Configuration
📄 Read: references/timescale.md
- Timescale slots and intervals
- Major and minor timescale settings
- Custom timescale format
- Time display options
- Work hours configuration
Working Hours
📄 Read: references/working-hours.md
- Setting working hours range
- Work hour highlighting
- Highlight color and styling
- Business hours for resources
- Non-working hour customization
Timezones
📄 Read: references/timezone.md
- IANA timezone support
- StartTimezone and EndTimezone fields
- Timezone conversion
- Daylight saving time handling
- Timezone-aware scheduling
Localization
📄 Read: references/localization.md
- Setting date format (DateFormat property)
- Time mode configuration (TimeFormat property)
- Right-to-left (RTL) support (EnableRtl property)
Virtual Scrolling
📄 Read: references/virtual-scrolling.md
- Virtual scrolling overview and when to use (100+ resources, 5,000+ appointments)
- Enable AllowVirtualScrolling in timeline views (TimelineDay, TimelineWeek, TimelineWorkWeek, TimelineMonth, TimelineYear)
- Virtual scrolling in Agenda view for large upcoming event lists
- Virtual scrolling in Timeline Month view with resource grouping
- Virtual scrolling benefits (reduced memory, smooth scrolling, DOM optimization)
- VirtualResourceCount property to control visible resources at once (default 30)
- VirtualResourceCount configuration for different screen sizes (20-50 standard, 100+ for large displays)
- Virtual scrolling with 300+ resources and sparse appointments
- Virtual scrolling with resource grouping and hierarchical organization
- Virtual scrolling combined with custom templates (ResourceHeaderTemplate, EventTemplate)
- Resource header templates with virtual scrolling for metadata display
- Event templates with virtual scrolling for custom event rendering
- Lazy loading appointments with EnableLazyLoading="true" property
- Lazy loading on-demand approach for viewport-based data retrieval
- Lazy loading with server-side appointment filtering by ResourceId
- Server-side controller implementation for lazy loading (ResourceId query params)
- Lazy loading parameters (StartDate, EndDate, ResourceId filtering)
- Virtual scrolling with DataManager for remote data binding
- Virtual scrolling and lazy loading combined for massive datasets
- Performance optimization with virtual scrolling (VirtualResourceCount tuning)
- Performance optimization with sparse data (not all resources have events daily)
- Performance optimization with EnableMaxHeight, AllowKeyboard settings
- CSS optimization for virtual scrolling (will-change property, min-height)
- Virtual scrolling limitations (not in Month/Year/MonthAgenda views)
- Virtual scrolling limitations (limited support in TimelineYear Vertical Orientation)
- When virtual scrolling is NOT beneficial (small datasets <100 resources)
- Combining virtual scrolling with MaxEventsPerRow for cell optimization
- Virtual scrolling with scroll-on-demand and automatic resource loading
- Memory management in virtual scrolling scenarios
- Testing virtual scrolling performance with actual large datasets
State Persistence
📄 Read: references/state-persistence.md
- Persisted properties (view, date)
- Local storage integration
Exporting and Importing
📄 Read: references/exporting.md
- Excel export to XLSX/CSV using ExportToExcelAsync
- Exporting with custom fields and field filtering
- Exporting recurring event occurrences as individual records (IncludeOccurrences)
- Exporting custom event data subset with CustomData option
- Customizing column headers with ExportFieldInfo
- Export with custom filename (FileName property)
- Excel file formats (XLSX vs CSV via ExportType)
- Export with specific date format (DateFormat option)
- Customize Excel sheet before export with OnExcelExporting event
- ExcelExport API for cell formatting, headers, styles
- ICS calendar export to .ics format (Outlook, Google Calendar compatible)
- ICS export with custom filename
- Importing events from external ICS files with ImportICalendarAsync
- File uploader integration for importing ICS files
- Merging imported events with existing appointments
- PrintAsync method without options (default print)
- PrintAsync method with PrintOptions (custom width/height)
- Print current view with all visible appointments
Dimensions
📄 Read: references/dimensions.md
- Height and width configuration
- Responsive sizing
- Auto-height for rows
- Cell and column dimensions
- Container constraints
Row Auto Height
📄 Read: references/row-auto-height.md
- Enable/disable auto height
- Row height calculation
- Content overflow handling
- Responsive row sizing
Performance and WebAssembly
📄 Read: references/webassembly-performance.md
- Avoid unnecessary component renders using
@keydirective - Use PreventRender to reduce re-renders after scheduler events
Accessibility
📄 Read: references/accessibility.md
- WCAG 2.2 Level A & AA compliance
- WAI-ARIA attributes and roles
- Keyboard navigation shortcuts
---
Quick Start Example
@using Syncfusion.Blazor.Schedule
<SfSchedule TValue="AppointmentData" Height="650px" @bind-SelectedDate="@CurrentDate">
<ScheduleEventSettings DataSource="@DataSource"></ScheduleEventSettings>
<ScheduleViews>
<ScheduleView Option="View.Day"></ScheduleView>
<ScheduleView Option="View.Week"></ScheduleView>
<ScheduleView Option="View.WorkWeek"></ScheduleView>
<ScheduleView Option="View.Month"></ScheduleView>
<ScheduleView Option="View.Agenda"></ScheduleView>
</ScheduleViews>
</SfSchedule>
@code{
DateTime CurrentDate = new DateTime(2026, 3, 24);
List<AppointmentData> DataSource = new List<AppointmentData>
{
new AppointmentData
{
Id = 1,
Subject = "Conference",
StartTime = new DateTime(2026, 3, 24, 9, 30, 0),
EndTime = new DateTime(2026, 3, 24, 11, 0, 0)
}
};
public class AppointmentData
{
public int Id { get; set; }
public string Subject { get; set; }
public string Location { get; set; }
public DateTime StartTime { get; set; }
public DateTime EndTime { get; set; }
public string Description { get; set; }
public bool IsAllDay { get; set; }
public string RecurrenceRule { get; set; }
public string RecurrenceException { get; set; }
public Nullable<int> RecurrenceID { get; set; }
}
}---
Common Patterns
1. CRUD Operations
- Create: Use
AddEventAsync()method or double-click cells for editor - Read: Use
GetEventsAsync()orGetCurrentViewEvents()orGetBlockEventsAsync() - Update: Modify appointment and use
SaveEventAsync() - Delete: Use
DeleteEventAsync()method or delete key for multi-select - Check availability: Use
IsSlotAvailableAsync()to prevent overlaps
2. Appointment Management
- Readonly appointments: Set
IsReadonly = trueon individual events or useReadonlyproperty - Block time slots: Set
IsBlock = trueto prevent scheduling on those slots - Overlapping control: Use
AllowOverlap="false"to prevent overlaps - Custom fields: Add custom properties beyond built-in fields (Status, Priority, etc.)
- Field mapping: Use
ScheduleFieldtags for custom field names
3. Appearance Customization
- Templates: Use
<Template>for custom appointment HTML - EventRendered: Apply dynamic CSS classes based on data
- CssClass: Apply predefined CSS classes from appointment data
- Tooltips: Enable with
EnableTooltip="true"and customize withTooltipTemplate - Cell styling: Use
OnRenderCellevent orCellTemplate
4. Event Handling
- ActionBegin: Intercept before operations (validate, cancel, check overlap)
- ActionCompleted: Execute after successful operations
- EventRendered: Customize appointment appearance
- OnDragStart / OnResizeStart: Control drag/resize behavior
- TooltipOpening: Conditionally show/hide tooltips
5. View Management
- Set
CurrentViewproperty to change active view - Configure each view independently with view-specific properties
- Use
DisplayNamefor custom view labels - Extend views with
Intervalproperty (e.g., 3-day view)
6. Recurring Events
- Use standard iCalendar
RecurrenceRuleformat (FREQ, INTERVAL, COUNT, UNTIL) - Add
RecurrenceExceptiondates to exclude occurrences - Use
RecurrenceIDfor edited occurrences - Support daily, weekly, monthly, yearly patterns with FREQ property
7. Data Binding
- Local: Bind
DataSourceto List<AppointmentData> - Remote: Bind to HTTP service returning data
- Use
Queryproperty for server-side filtering - Call
RefreshEventsAsync()to reload data without full refresh
---
Key Props and Configuration
| Property | Purpose | Example |
|---|---|---|
Height | Scheduler height in pixels/percentage | Height="650px" |
Width | Scheduler width in pixels/percentage | Width="100%" |
CurrentView | Active view (Day, Week, Month, etc.) | CurrentView="View.Week" |
SelectedDate | Currently displayed date | @bind-SelectedDate="@date" |
AllowDragAndDrop | Enable/disable drag functionality | AllowDragAndDrop="true" |
AllowResizing | Enable/disable resize functionality | AllowResizing="true" |
AllowMultiDrag | Allow dragging multiple appointments | AllowMultiDrag="true" |
AllowOverlap | Prevent overlapping appointments | AllowOverlap="false" |
AllowInline | Quick inline creation on cell click | AllowInline="true" |
Readonly | View-only mode (no CRUD) | Readonly="true" |
MinDate | Minimum date boundary | MinDate="new DateTime(2026,1,1)" |
MaxDate | Maximum date boundary | MaxDate="new DateTime(2026,12,31)" |
CssClass | Custom CSS class for styling | CssClass="custom-scheduler" |
EnableMaxHeight | Appointments occupy full cell height | EnableMaxHeight="true" |
EnableIndicator | Show indicator for multiple appointments | EnableIndicator="true" |
EnableAutoRowHeight | Auto-adjust row heights for content | EnableAutoRowHeight="true" |
---
Common Use Cases
1. Employee Scheduling - Multiple resources with drag-drop and approval workflow 2. Meeting Rooms Reservation - Resource-based booking with timezone support 3. Doctor's Appointments - Recurring slots with patient blocking 4. Project Task Management - Timeline views with progress tracking 5. Educational Timetable - Multiple classes with resource grouping 6. Shift Management - Working hours, shift patterns with recurrence 7. Event Calendar - Public events with recurrence and filtering 8. Field Service Dispatch - Mobile-friendly with offline support
---
Next Steps: Read the appropriate reference file based on your use case to understand specific features and implementation details.
Appointment Customization
Table of Contents
- Customizing Appointments with Template
- Using EventRendered Event
- Customizing with Attributes
- Using CssClass Field
- Using CssClass Property on Scheduler
- Display Tooltips for Appointments
- Conditional Customization
- Important Notes
Customizing Appointments with Template
Apply custom HTML templates to change appointment appearance:
@using Syncfusion.Blazor.Schedule
<SfSchedule TValue="AppointmentData" Height="650px" @bind-SelectedDate="@CurrentDate">
<ScheduleEventSettings DataSource="@DataSource">
<Template>
<div class="appointment-template">
<div class="subject">@((context as AppointmentData).Subject)</div>
<div class="time">@((context as AppointmentData).StartTime.ToString("hh:mm tt"))</div>
<div class="location">📍 @((context as AppointmentData).Location)</div>
</div>
</Template>
</ScheduleEventSettings>
<ScheduleViews>
<ScheduleView Option="View.Day"></ScheduleView>
<ScheduleView Option="View.Week"></ScheduleView>
<ScheduleView Option="View.Month"></ScheduleView>
</ScheduleViews>
</SfSchedule>
<style>
.appointment-template {
padding: 5px;
background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
color: white;
border-radius: 4px;
height: 100%;
}
.appointment-template .subject {
font-weight: bold;
margin-bottom: 2px;
}
.appointment-template .time {
font-size: 12px;
opacity: 0.9;
}
.appointment-template .location {
font-size: 11px;
}
</style>
@code{
DateTime CurrentDate = new DateTime(2026, 3, 24);
List<AppointmentData> DataSource = new List<AppointmentData>
{
new AppointmentData
{
Id = 1,
Subject = "Team Meeting",
Location = "Room 101",
StartTime = new DateTime(2026, 3, 24, 10, 0, 0),
EndTime = new DateTime(2026, 3, 24, 11, 0, 0)
}
};
public class AppointmentData
{
public int Id { get; set; }
public string Subject { get; set; }
public string Location { get; set; }
public DateTime StartTime { get; set; }
public DateTime EndTime { get; set; }
}
}Using EventRendered Event
Customize appointments based on conditions before rendering:
@using Syncfusion.Blazor.Schedule
<SfSchedule TValue="AppointmentData" Height="650px" @bind-SelectedDate="@CurrentDate">
<ScheduleEvents TValue="AppointmentData" EventRendered="OnEventRendered"></ScheduleEvents>
<ScheduleEventSettings DataSource="@DataSource"></ScheduleEventSettings>
<ScheduleViews>
<ScheduleView Option="View.Day"></ScheduleView>
<ScheduleView Option="View.Week"></ScheduleView>
<ScheduleView Option="View.Month"></ScheduleView>
</ScheduleViews>
</SfSchedule>
<style>
.e-schedule .e-appointment.high-priority {
background-color: #ff4757 !important;
border-left: 4px solid #c92a2a !important;
}
.e-schedule .e-appointment.medium-priority {
background-color: #ffa502 !important;
border-left: 4px solid #ff6348 !important;
}
.e-schedule .e-appointment.completed {
background-color: #2ed573 !important;
text-decoration: line-through;
opacity: 0.7;
}
</style>
@code{
DateTime CurrentDate = new DateTime(2026, 3, 24);
public void OnEventRendered(EventRenderedArgs<AppointmentData> args)
{
if (args.Data.Priority == "High")
{
args.CssClasses = new List<string> { "high-priority" };
}
else if (args.Data.Priority == "Medium")
{
args.CssClasses = new List<string> { "medium-priority" };
}
if (args.Data.Status == "Completed")
{
args.CssClasses.Add("completed");
}
}
List<AppointmentData> DataSource = new List<AppointmentData>
{
new AppointmentData
{
Id = 1,
Subject = "Critical Issue",
Priority = "High",
Status = "Active",
StartTime = new DateTime(2026, 3, 24, 9, 0, 0),
EndTime = new DateTime(2026, 3, 24, 10, 0, 0)
},
new AppointmentData
{
Id = 2,
Subject = "Review Task",
Priority = "Medium",
Status = "Completed",
StartTime = new DateTime(2026, 3, 24, 11, 0, 0),
EndTime = new DateTime(2026, 3, 24, 12, 0, 0)
}
};
public class AppointmentData
{
public int Id { get; set; }
public string Subject { get; set; }
public DateTime StartTime { get; set; }
public DateTime EndTime { get; set; }
public string Priority { get; set; }
public string Status { get; set; }
}
}Customizing with Attributes
Add or modify HTML attributes dynamically:
@using Syncfusion.Blazor.Schedule
<SfSchedule TValue="AppointmentData" Height="650px" @bind-SelectedDate="@CurrentDate">
<ScheduleEvents TValue="AppointmentData" EventRendered="OnEventRendered"></ScheduleEvents>
<ScheduleEventSettings DataSource="@DataSource"></ScheduleEventSettings>
<ScheduleViews>
<ScheduleView Option="View.Week"></ScheduleView>
</ScheduleViews>
</SfSchedule>
@code{
DateTime CurrentDate = new DateTime(2026, 3, 24);
public void OnEventRendered(EventRenderedArgs<AppointmentData> args)
{
var attributes = new Dictionary<string, object>
{
{ "style", $"background: {GetColorByStatus(args.Data.Status)}; border-radius: 4px;" },
{ "title", args.Data.Subject + " - " + args.Data.Status },
{ "data-status", args.Data.Status }
};
args.Attributes = attributes;
}
private string GetColorByStatus(string status)
{
return status switch
{
"Confirmed" => "#4CAF50",
"Pending" => "#FF9800",
"Cancelled" => "#F44336",
_ => "#2196F3"
};
}
List<AppointmentData> DataSource = new List<AppointmentData>
{
new AppointmentData
{
Id = 1,
Subject = "Confirmed",
Status = "Confirmed",
StartTime = new DateTime(2026, 3, 24, 9, 0, 0),
EndTime = new DateTime(2026, 3, 24, 10, 0, 0)
}
};
public class AppointmentData
{
public int Id { get; set; }
public string Subject { get; set; }
public DateTime StartTime { get; set; }
public DateTime EndTime { get; set; }
public string Status { get; set; }
}
}Using CssClass Field
Apply CSS classes directly from data model:
@using Syncfusion.Blazor.Schedule
<SfSchedule TValue="AppointmentData" Height="650px" @bind-SelectedDate="@CurrentDate">
<ScheduleEventSettings DataSource="@DataSource"></ScheduleEventSettings>
<ScheduleViews>
<ScheduleView Option="View.Week"></ScheduleView>
<ScheduleView Option="View.Month"></ScheduleView>
</ScheduleViews>
</SfSchedule>
<style>
/* Event type styles */
.e-schedule .e-appointment.meeting {
background-color: #3498db;
color: white;
}
.e-schedule .e-appointment.conference {
background-color: #9b59b6;
color: white;
}
.e-schedule .e-appointment.training {
background-color: #1abc9c;
color: white;
}
.e-schedule .e-appointment.lunch {
background-color: #e74c3c;
color: white;
border-bottom: 3px dotted #c0392b;
}
</style>
@code{
DateTime CurrentDate = new DateTime(2026, 3, 24);
List<AppointmentData> DataSource = new List<AppointmentData>
{
new AppointmentData
{
Id = 1,
Subject = "Team Meeting",
CssClass = "meeting",
StartTime = new DateTime(2026, 3, 24, 9, 0, 0),
EndTime = new DateTime(2026, 3, 24, 10, 0, 0)
},
new AppointmentData
{
Id = 2,
Subject = "Annual Conference",
CssClass = "conference",
StartTime = new DateTime(2026, 3, 24, 10, 30, 0),
EndTime = new DateTime(2026, 3, 24, 12, 0, 0)
},
new AppointmentData
{
Id = 3,
Subject = "Lunch Break",
CssClass = "lunch",
StartTime = new DateTime(2026, 3, 24, 12, 0, 0),
EndTime = new DateTime(2026, 3, 24, 13, 0, 0)
}
};
public class AppointmentData
{
public int Id { get; set; }
public string Subject { get; set; }
public DateTime StartTime { get; set; }
public DateTime EndTime { get; set; }
public string CssClass { get; set; }
}
}Using CssClass Property on Scheduler
Apply global styles to all appointments:
@using Syncfusion.Blazor.Schedule
<SfSchedule TValue="AppointmentData" Height="550px" CssClass="custom-scheduler" @bind-SelectedDate="@CurrentDate">
<ScheduleEventSettings DataSource="@DataSource"></ScheduleEventSettings>
<ScheduleViews>
<ScheduleView Option="View.Week"></ScheduleView>
<ScheduleView Option="View.Month"></ScheduleView>
</ScheduleViews>
</SfSchedule>
<style>
/* Apply custom styles to all appointments in this scheduler */
.custom-scheduler.e-schedule .e-appointment {
border-radius: 8px;
box-shadow: 0 2px 4px rgba(0,0,0,0.1);
font-weight: 500;
letter-spacing: 0.5px;
}
.custom-scheduler.e-schedule .e-appointment:hover {
transform: translateY(-2px);
box-shadow: 0 4px 8px rgba(0,0,0,0.15);
}
</style>
@code{
DateTime CurrentDate = new DateTime(2026, 3, 24);
List<AppointmentData> DataSource = new List<AppointmentData>
{
new AppointmentData
{
Id = 1,
Subject = "Meeting",
StartTime = new DateTime(2026, 3, 24, 10, 0, 0),
EndTime = new DateTime(2026, 3, 24, 11, 0, 0)
}
};
public class AppointmentData
{
public int Id { get; set; }
public string Subject { get; set; }
public DateTime StartTime { get; set; }
public DateTime EndTime { get; set; }
}
}Display Tooltips for Appointments
Show additional information on hover:
@using Syncfusion.Blazor.Schedule
<SfSchedule TValue="AppointmentData" Height="650px" @bind-SelectedDate="@CurrentDate">
<ScheduleEventSettings DataSource="@DataSource" EnableTooltip="true">
<TooltipTemplate>
<div class="tooltip-content">
<strong>@((context as AppointmentData).Subject)</strong>
<div>📍 @((context as AppointmentData).Location)</div>
<div>⏰ @((context as AppointmentData).StartTime.ToString("hh:mm tt")) - @((context as AppointmentData).EndTime.ToString("hh:mm tt"))</div>
<div>📝 @((context as AppointmentData).Description)</div>
</div>
</TooltipTemplate>
</ScheduleEventSettings>
<ScheduleViews>
<ScheduleView Option="View.Month"></ScheduleView>
</ScheduleViews>
</SfSchedule>
<style>
.tooltip-content {
padding: 10px;
background: #333;
color: white;
border-radius: 4px;
font-size: 12px;
}
</style>
@code{
DateTime CurrentDate = new DateTime(2026, 3, 24);
List<AppointmentData> DataSource = new List<AppointmentData>
{
new AppointmentData
{
Id = 1,
Subject = "Project Kickoff",
Location = "Room 201",
Description = "Discuss project scope and timeline",
StartTime = new DateTime(2026, 3, 24, 9, 0, 0),
EndTime = new DateTime(2026, 3, 24, 10, 30, 0)
}
};
public class AppointmentData
{
public int Id { get; set; }
public string Subject { get; set; }
public string Location { get; set; }
public string Description { get; set; }
public DateTime StartTime { get; set; }
public DateTime EndTime { get; set; }
}
}Conditional Customization
Customize based on appointment data:
@using Syncfusion.Blazor.Schedule
<SfSchedule TValue="AppointmentData" Height="650px" @bind-SelectedDate="@CurrentDate">
<ScheduleEvents TValue="AppointmentData" EventRendered="OnEventRendered"></ScheduleEvents>
<ScheduleEventSettings DataSource="@DataSource">
<Template>
<div class="@GetTemplateClass((context as AppointmentData))">
<span class="urgency">@GetUrgencyIcon((context as AppointmentData))</span>
<strong>@((context as AppointmentData).Subject)</strong>
</div>
</Template>
</ScheduleEventSettings>
<ScheduleViews>
<ScheduleView Option="View.Week"></ScheduleView>
</ScheduleViews>
</SfSchedule>
@code{
DateTime CurrentDate = new DateTime(2026, 3, 24);
private string GetTemplateClass(AppointmentData data)
{
return data.Priority switch
{
"High" => "appointment high-urgent",
"Medium" => "appointment medium-urgent",
_ => "appointment low-urgent"
};
}
private string GetUrgencyIcon(AppointmentData data)
{
return data.Priority switch
{
"High" => "🔴",
"Medium" => "🟡",
_ => "🟢"
};
}
List<AppointmentData> DataSource = new List<AppointmentData>
{
new AppointmentData
{
Id = 1,
Subject = "Critical",
Priority = "High",
StartTime = new DateTime(2026, 3, 24, 10, 0, 0),
EndTime = new DateTime(2026, 3, 24, 11, 0, 0)
}
};
public class AppointmentData
{
public int Id { get; set; }
public string Subject { get; set; }
public DateTime StartTime { get; set; }
public DateTime EndTime { get; set; }
public string Priority { get; set; }
}
}Important Notes
- Templates cannot override
height,width,top,left,right, anddisplayCSS properties - Use
EventRenderedfor dynamic styles based on data - Use
Templatefor custom HTML structure - Combine both for maximum customization
- Always consider accessibility when customizing colors
Drag and Drop Appointments
Table of Contents
- Enable Drag and Drop
- Disable Drag and Drop
- Drag Multiple Appointments
- Prevent Drag on Specific Targets
- Control Scroll During Drag
- Adjust Scroll Speed
- Set Drag Time Interval
- Auto-Navigate While Dragging
- Handle Drag Completion
- Drag Events Between Schedulers
- Notes
Enable Drag and Drop
The AllowDragAndDrop property enables dragging appointments to new times:
@using Syncfusion.Blazor.Schedule
<SfSchedule TValue="AppointmentData" Height="550px" AllowDragAndDrop="true" @bind-SelectedDate="@CurrentDate">
<ScheduleEventSettings DataSource="@DataSource"></ScheduleEventSettings>
<ScheduleViews>
<ScheduleView Option="View.Week"></ScheduleView>
<ScheduleView Option="View.Month"></ScheduleView>
</ScheduleViews>
</SfSchedule>
@code{
DateTime CurrentDate = new DateTime(2026, 3, 24);
List<AppointmentData> DataSource = new List<AppointmentData>
{
new AppointmentData { Id = 1, Subject = "Meeting", StartTime = new DateTime(2026, 3, 24, 9, 30, 0), EndTime = new DateTime(2026, 3, 24, 11, 0, 0)}
};
public class AppointmentData
{
public int Id { get; set; }
public string Subject { get; set; }
public DateTime StartTime { get; set; }
public DateTime EndTime { get; set; }
}
}Disable Drag and Drop
Set AllowDragAndDrop="false" to prevent dragging:
<SfSchedule TValue="AppointmentData" Height="550px" AllowDragAndDrop="false" @bind-SelectedDate="@CurrentDate">
<ScheduleEventSettings DataSource="@DataSource"></ScheduleEventSettings>
<ScheduleViews>
<ScheduleView Option="View.Week"></ScheduleView>
</ScheduleViews>
</SfSchedule>Drag Multiple Appointments
Enable AllowMultiDrag to drag multiple selected events:
@using Syncfusion.Blazor.Schedule
<SfSchedule TValue="AppointmentData" Height="550px" AllowMultiDrag="true" @bind-SelectedDate="@CurrentDate">
<ScheduleEventSettings DataSource="@DataSource"></ScheduleEventSettings>
<ScheduleViews>
<ScheduleView Option="View.Week"></ScheduleView>
</ScheduleViews>
</SfSchedule>
@code{
DateTime CurrentDate = new DateTime(2026, 3, 24);
List<AppointmentData> DataSource = new List<AppointmentData>
{
new AppointmentData { Id = 1, Subject = "Meeting 1", StartTime = new DateTime(2026, 3, 24, 9, 30, 0), EndTime = new DateTime(2026, 3, 24, 11, 0, 0)},
new AppointmentData { Id = 2, Subject = "Meeting 2", StartTime = new DateTime(2026, 3, 24, 12, 0, 0), EndTime = new DateTime(2026, 3, 24, 13, 0, 0)}
};
public class AppointmentData
{
public int Id { get; set; }
public string Subject { get; set; }
public DateTime StartTime { get; set; }
public DateTime EndTime { get; set; }
}
}Users hold Ctrl and click multiple events, then drag them together.
Prevent Drag on Specific Targets
Use OnDragStart event to exclude certain areas:
@using Syncfusion.Blazor.Schedule
<SfSchedule TValue="AppointmentData" Height="550px" @bind-SelectedDate="@CurrentDate">
<ScheduleEvents TValue="AppointmentData" OnDragStart="OnAppointmentDrag"></ScheduleEvents>
<ScheduleEventSettings DataSource="@DataSource"></ScheduleEventSettings>
<ScheduleViews>
<ScheduleView Option="View.Week"></ScheduleView>
</ScheduleViews>
</SfSchedule>
@code{
DateTime CurrentDate = new DateTime(2026, 3, 24);
public void OnAppointmentDrag(DragEventArgs<AppointmentData> args)
{
// Prevent dragging from header and all-day cells
args.ExcludeSelectors = "e-header-cells,e-all-day-cells";
}
List<AppointmentData> DataSource = new List<AppointmentData>
{
new AppointmentData { Id = 1, Subject = "Meeting", StartTime = new DateTime(2026, 3, 24, 9, 30, 0), EndTime = new DateTime(2026, 3, 24, 11, 0, 0)}
};
public class AppointmentData
{
public int Id { get; set; }
public string Subject { get; set; }
public DateTime StartTime { get; set; }
public DateTime EndTime { get; set; }
}
}Control Scroll During Drag
Disable automatic scrolling at edges:
@using Syncfusion.Blazor.Schedule
<SfSchedule TValue="AppointmentData" Height="550px" @bind-SelectedDate="@CurrentDate">
<ScheduleEvents TValue="AppointmentData" OnDragStart="OnAppointmentDrag"></ScheduleEvents>
<ScheduleEventSettings DataSource="@DataSource"></ScheduleEventSettings>
<ScheduleViews>
<ScheduleView Option="View.Week"></ScheduleView>
</ScheduleViews>
</SfSchedule>
@code{
DateTime CurrentDate = new DateTime(2026, 3, 24);
public void OnAppointmentDrag(DragEventArgs<AppointmentData> args)
{
// Disable scrolling
args.Scroll.Enable = false;
}
List<AppointmentData> DataSource = new List<AppointmentData>
{
new AppointmentData { Id = 1, Subject = "Meeting", StartTime = new DateTime(2026, 3, 24, 9, 30, 0), EndTime = new DateTime(2026, 3, 24, 11, 0, 0)}
};
public class AppointmentData
{
public int Id { get; set; }
public string Subject { get; set; }
public DateTime StartTime { get; set; }
public DateTime EndTime { get; set; }
}
}Adjust Scroll Speed
Control how fast the scheduler scrolls during drag:
@using Syncfusion.Blazor.Schedule
<SfSchedule TValue="AppointmentData" Height="550px" @bind-SelectedDate="@CurrentDate">
<ScheduleEvents TValue="AppointmentData" OnDragStart="OnAppointmentDrag"></ScheduleEvents>
<ScheduleEventSettings DataSource="@DataSource"></ScheduleEventSettings>
<ScheduleViews>
<ScheduleView Option="View.Week"></ScheduleView>
</ScheduleViews>
</SfSchedule>
@code{
DateTime CurrentDate = new DateTime(2026, 3, 24);
public void OnAppointmentDrag(DragEventArgs<AppointmentData> args)
{
// Scroll by 5 minutes every 200ms
args.Scroll.ScrollBy = 5;
args.Scroll.TimeDelay = 200;
}
List<AppointmentData> DataSource = new List<AppointmentData>
{
new AppointmentData { Id = 1, Subject = "Meeting", StartTime = new DateTime(2026, 3, 24, 9, 30, 0), EndTime = new DateTime(2026, 3, 24, 11, 0, 0)}
};
public class AppointmentData
{
public int Id { get; set; }
public string Subject { get; set; }
public DateTime StartTime { get; set; }
public DateTime EndTime { get; set; }
}
}Set Drag Time Interval
Change the increment interval during dragging:
@using Syncfusion.Blazor.Schedule
<SfSchedule TValue="AppointmentData" Height="550px" @bind-SelectedDate="@CurrentDate">
<ScheduleEvents TValue="AppointmentData" OnDragStart="OnAppointmentDrag"></ScheduleEvents>
<ScheduleEventSettings DataSource="@DataSource"></ScheduleEventSettings>
<ScheduleViews>
<ScheduleView Option="View.Week"></ScheduleView>
</ScheduleViews>
</SfSchedule>
@code{
DateTime CurrentDate = new DateTime(2026, 3, 24);
public void OnAppointmentDrag(DragEventArgs<AppointmentData> args)
{
// Drag in 15-minute intervals instead of default 30 minutes
args.Interval = 15;
}
List<AppointmentData> DataSource = new List<AppointmentData>
{
new AppointmentData { Id = 1, Subject = "Meeting", StartTime = new DateTime(2026, 3, 24, 9, 30, 0), EndTime = new DateTime(2026, 3, 24, 11, 0, 0)}
};
public class AppointmentData
{
public int Id { get; set; }
public string Subject { get; set; }
public DateTime StartTime { get; set; }
public DateTime EndTime { get; set; }
}
}Auto-Navigate While Dragging
Enable date range navigation while dragging at edges:
@using Syncfusion.Blazor.Schedule
<SfSchedule TValue="AppointmentData" Height="550px" @bind-SelectedDate="@CurrentDate">
<ScheduleEvents TValue="AppointmentData" OnDragStart="OnAppointmentDrag"></ScheduleEvents>
<ScheduleEventSettings DataSource="@DataSource"></ScheduleEventSettings>
<ScheduleViews>
<ScheduleView Option="View.Week"></ScheduleView>
</ScheduleViews>
</SfSchedule>
@code{
DateTime CurrentDate = new DateTime(2026, 3, 24);
public void OnAppointmentDrag(DragEventArgs<AppointmentData> args)
{
// Enable navigation - hold at edge for 2 seconds to auto-navigate
args.Navigation.Enable = true;
args.Navigation.TimeDelay = 2000;
}
List<AppointmentData> DataSource = new List<AppointmentData>
{
new AppointmentData { Id = 1, Subject = "Meeting", StartTime = new DateTime(2026, 3, 24, 9, 30, 0), EndTime = new DateTime(2026, 3, 24, 11, 0, 0)}
};
public class AppointmentData
{
public int Id { get; set; }
public string Subject { get; set; }
public DateTime StartTime { get; set; }
public DateTime EndTime { get; set; }
}
}Handle Drag Completion
Execute actions when drag completes:
@using Syncfusion.Blazor.Schedule
<SfSchedule @ref="ScheduleRef" TValue="AppointmentData" Height="550px" @bind-SelectedDate="@CurrentDate">
<ScheduleEvents TValue="AppointmentData" Dragged="OnDragComplete"></ScheduleEvents>
<ScheduleEventSettings DataSource="@DataSource"></ScheduleEventSettings>
<ScheduleViews>
<ScheduleView Option="View.Week"></ScheduleView>
</ScheduleViews>
</SfSchedule>
@code{
DateTime CurrentDate = new DateTime(2026, 3, 24);
SfSchedule<AppointmentData> ScheduleRef;
public async Task OnDragComplete(DragEventArgs<AppointmentData> args)
{
// Show editor after drag completes
args.Cancel = true;
await ScheduleRef.OpenEditorAsync(args.Data, CurrentAction.Save);
}
List<AppointmentData> DataSource = new List<AppointmentData>
{
new AppointmentData { Id = 1, Subject = "Meeting", StartTime = new DateTime(2026, 3, 24, 9, 30, 0), EndTime = new DateTime(2026, 3, 24, 11, 0, 0)}
};
public class AppointmentData
{
public int Id { get; set; }
public string Subject { get; set; }
public DateTime StartTime { get; set; }
public DateTime EndTime { get; set; }
}
}Drag Events Between Schedulers
Move events between two schedulers:
@using Syncfusion.Blazor.Schedule
<div class="row">
<div class="col-lg-6">
<h3>Scheduler 1</h3>
<SfSchedule @ref="Schedule1Ref" Height="550px" TValue="AppointmentData" EventDragArea=".ScheduleContainer" @bind-SelectedDate="@CurrentDate">
<ScheduleEvents TValue="AppointmentData" Dragged="OnDragged"></ScheduleEvents>
<ScheduleEventSettings DataSource="@Schedule1Data"></ScheduleEventSettings>
<ScheduleViews>
<ScheduleView Option="View.Week"></ScheduleView>
</ScheduleViews>
</SfSchedule>
</div>
<div class="col-lg-6">
<h3>Scheduler 2</h3>
<SfSchedule @ref="Schedule2Ref" Height="550px" TValue="AppointmentData" CssClass="ScheduleContainer" SelectedDate="@CurrentDate">
<ScheduleEventSettings DataSource="@Schedule2Data"></ScheduleEventSettings>
<ScheduleViews>
<ScheduleView Option="View.Week"></ScheduleView>
</ScheduleViews>
</SfSchedule>
</div>
</div>
@code {
DateTime CurrentDate = new DateTime(2026, 3, 24);
SfSchedule<AppointmentData> Schedule1Ref;
SfSchedule<AppointmentData> Schedule2Ref;
List<AppointmentData> Schedule1Data = new List<AppointmentData>
{
new AppointmentData { Id = 1, Subject = "Meeting", StartTime = new DateTime(2026, 3, 24, 9, 30, 0), EndTime = new DateTime(2026, 3, 24, 11, 0, 0)}
};
List<AppointmentData> Schedule2Data = new List<AppointmentData>();
public async Task OnDragged(DragEventArgs<AppointmentData> args)
{
await Schedule1Ref.DeleteEventAsync(args.Data.Id);
Random random = new Random();
args.Data.Id = random.Next(1000);
await Schedule2Ref.AddEventAsync(args.Data);
}
public class AppointmentData
{
public int Id { get; set; }
public string Subject { get; set; }
public DateTime StartTime { get; set; }
public DateTime EndTime { get; set; }
}
}Notes
- Drag-drop not supported in Agenda and Month-Agenda views
- Multi-drag not supported on mobile devices
- Default drag interval is 30 minutes
- Use events to customize drag behavior
Resizing Appointments
Table of Contents
- Enable Resizing
- Disable Resizing
- Disable Scroll During Resize
- Control Scroll Speed During Resize
- Set Resize Time Interval
- Notes
Enable Resizing
Use AllowResizing="true" to enable appointment resizing:
@using Syncfusion.Blazor.Schedule
<SfSchedule TValue="AppointmentData" Height="550px" AllowResizing="true" @bind-SelectedDate="@CurrentDate">
<ScheduleEventSettings DataSource="@DataSource"></ScheduleEventSettings>
<ScheduleViews>
<ScheduleView Option="View.Week"></ScheduleView>
</ScheduleViews>
</SfSchedule>
@code{
DateTime CurrentDate = new DateTime(2026, 3, 24);
List<AppointmentData> DataSource = new List<AppointmentData>
{
new AppointmentData { Id = 1, Subject = "Meeting", StartTime = new DateTime(2026, 3, 24, 9, 30, 0), EndTime = new DateTime(2026, 3, 24, 11, 0, 0)}
};
public class AppointmentData
{
public int Id { get; set; }
public string Subject { get; set; }
public DateTime StartTime { get; set; }
public DateTime EndTime { get; set; }
}
}Disable Resizing
Set AllowResizing="false":
<SfSchedule TValue="AppointmentData" Height="550px" AllowResizing="false" @bind-SelectedDate="@CurrentDate">
<ScheduleEventSettings DataSource="@DataSource"></ScheduleEventSettings>
<ScheduleViews>
<ScheduleView Option="View.Week"></ScheduleView>
</ScheduleViews>
</SfSchedule>Disable Scroll During Resize
Prevent automatic scrolling when resizing at edges:
@using Syncfusion.Blazor.Schedule
<SfSchedule TValue="AppointmentData" Height="550px" @bind-SelectedDate="@CurrentDate">
<ScheduleEvents TValue="AppointmentData" OnResizeStart="OnAppointmentResize"></ScheduleEvents>
<ScheduleEventSettings DataSource="@DataSource"></ScheduleEventSettings>
<ScheduleViews>
<ScheduleView Option="View.Week"></ScheduleView>
</ScheduleViews>
</SfSchedule>
@code{
DateTime CurrentDate = new DateTime(2026, 3, 24);
public void OnAppointmentResize(ResizeEventArgs<AppointmentData> args)
{
args.Scroll.Enable = false;
}
List<AppointmentData> DataSource = new List<AppointmentData>
{
new AppointmentData { Id = 1, Subject = "Meeting", StartTime = new DateTime(2026, 3, 24, 9, 30, 0), EndTime = new DateTime(2026, 3, 24, 11, 0, 0)}
};
public class AppointmentData
{
public int Id { get; set; }
public string Subject { get; set; }
public DateTime StartTime { get; set; }
public DateTime EndTime { get; set; }
}
}Control Scroll Speed During Resize
Adjust how fast scrolling occurs:
@using Syncfusion.Blazor.Schedule
<SfSchedule TValue="AppointmentData" Height="550px" @bind-SelectedDate="@CurrentDate">
<ScheduleEvents TValue="AppointmentData" OnResizeStart="OnAppointmentResize"></ScheduleEvents>
<ScheduleEventSettings DataSource="@DataSource"></ScheduleEventSettings>
<ScheduleViews>
<ScheduleView Option="View.Week"></ScheduleView>
</ScheduleViews>
</SfSchedule>
@code{
DateTime CurrentDate = new DateTime(2026, 3, 24);
public void OnAppointmentResize(ResizeEventArgs<AppointmentData> args)
{
// Scroll by 15 minutes when resizing at edge
args.Scroll.ScrollBy = 15;
}
List<AppointmentData> DataSource = new List<AppointmentData>
{
new AppointmentData { Id = 1, Subject = "Meeting", StartTime = new DateTime(2026, 3, 24, 9, 30, 0), EndTime = new DateTime(2026, 3, 24, 11, 0, 0)}
};
public class AppointmentData
{
public int Id { get; set; }
public string Subject { get; set; }
public DateTime StartTime { get; set; }
public DateTime EndTime { get; set; }
}
}Set Resize Time Interval
Change the increment interval during resizing:
@using Syncfusion.Blazor.Schedule
<SfSchedule TValue="AppointmentData" Height="550px" @bind-SelectedDate="@CurrentDate">
<ScheduleEvents TValue="AppointmentData" OnResizeStart="OnAppointmentResize"></ScheduleEvents>
<ScheduleEventSettings DataSource="@DataSource"></ScheduleEventSettings>
<ScheduleViews>
<ScheduleView Option="View.Week"></ScheduleView>
</ScheduleViews>
</SfSchedule>
@code{
DateTime CurrentDate = new DateTime(2026, 3, 24);
public void OnAppointmentResize(ResizeEventArgs<AppointmentData> args)
{
// Resize in 15-minute increments instead of default 30 minutes
args.Interval = 15;
}
List<AppointmentData> DataSource = new List<AppointmentData>
{
new AppointmentData { Id = 1, Subject = "Meeting", StartTime = new DateTime(2026, 3, 24, 9, 30, 0), EndTime = new DateTime(2026, 3, 24, 11, 0, 0)}
};
public class AppointmentData
{
public int Id { get; set; }
public string Subject { get; set; }
public DateTime StartTime { get; set; }
public DateTime EndTime { get; set; }
}
}Notes
- Resizing not supported in Agenda and Month-Agenda views
- Default resize interval is 30 minutes
- Resize handlers appear on top and bottom of appointments
- Resizing adjusts EndTime (top) and StartTime (bottom)
Appointments and Event Fields
Table of Contents
- Built-in Event Fields
- Binding Different Field Names
- Event Field Settings
- Adding Custom Fields
- Normal Events
- Spanned Events
- All-Day Events
- Block Date and Time
- Read-Only Appointments
- Overlapping Events
- Slot Availability
- Appointment Appearance
- Tooltips
- Appointment Selection
- Retrieving Appointments
- Filtering Appointments
- Refresh Appointments
Built-in Event Fields
The Scheduler event object contains the following built-in fields that map to appointment properties:
| Field | Type | Required | Description |
|---|---|---|---|
Id | int | Yes (for CRUD) | Unique identifier for each event |
Subject | string | No | Event title/summary (default: empty) |
StartTime | DateTime | Yes | Appointment start time |
EndTime | DateTime | Yes | Appointment end time |
Location | string | No | Event location |
Description | string | No | Event details |
IsAllDay | bool | No | All-day event flag (default: false) |
StartTimezone | string | No | IANA timezone for start time |
EndTimezone | string | No | IANA timezone for end time |
RecurrenceRule | string | No | iCalendar recurrence pattern |
RecurrenceID | int? | No | Parent event ID for edited occurrences |
RecurrenceException | string | No | Excluded dates from recurrence (ISO format) |
IsReadonly | bool | No | Make event read-only (default: false) |
IsBlock | bool | No | Block time slot (default: false) |
CssClass | string | No | Custom CSS class for styling |
Note: To create an event, minimum required fields are StartTime and EndTime. For remote data binding, Id field is mandatory for CRUD operations.
Binding Different Field Names
When your data model uses different field names, map them explicitly using ScheduleField:
@using Syncfusion.Blazor.Schedule
<SfSchedule TValue="AppointmentData" Height="550px" @bind-SelectedDate="@CurrentDate">
<ScheduleEventSettings DataSource="@DataSource">
<ScheduleField Id="TravelId" IsBlock="IsDisabled">
<FieldSubject Name="TravelSummary"></FieldSubject>
<FieldLocation Name="Source"></FieldLocation>
<FieldDescription Name="Comments"></FieldDescription>
<FieldIsAllDay Name="FullDay"></FieldIsAllDay>
<FieldStartTime Name="DepartureTime"></FieldStartTime>
<FieldEndTime Name="ArrivalTime"></FieldEndTime>
<FieldStartTimezone Name="Origin"></FieldStartTimezone>
<FieldEndTimezone Name="Destination"></FieldEndTimezone>
</ScheduleField>
</ScheduleEventSettings>
<ScheduleViews>
<ScheduleView Option="View.Day"></ScheduleView>
<ScheduleView Option="View.Week"></ScheduleView>
<ScheduleView Option="View.WorkWeek"></ScheduleView>
<ScheduleView Option="View.Month"></ScheduleView>
<ScheduleView Option="View.Agenda"></ScheduleView>
</ScheduleViews>
</SfSchedule>
@code{
DateTime CurrentDate = new DateTime(2020, 1, 10);
List<AppointmentData> DataSource = new List<AppointmentData>
{
new AppointmentData
{
TravelId = 1,
TravelSummary = "Paris",
DepartureTime = new DateTime(2020, 1, 10, 10, 0, 0),
ArrivalTime = new DateTime(2020, 1, 10, 12, 30, 0),
Source = "London",
Comments = "Summer vacation planned for outstation.",
Origin = "Asia/Yekaterinburg",
Destination = "Asia/Yekaterinburg"
},
new AppointmentData
{
TravelId = 2,
TravelSummary = "Tokyo",
DepartureTime = new DateTime(2020, 1, 11, 10, 0, 0),
ArrivalTime = new DateTime(2020, 1, 11, 12, 30, 0),
Source = "Beijing",
Comments = "Conference on emerging technologies.",
Origin = "Asia/Yekaterinburg",
Destination = "Asia/Yekaterinburg",
IsDisabled = true
}
};
public class AppointmentData
{
public int TravelId { get; set; }
public string TravelSummary { get; set; }
public DateTime DepartureTime { get; set; }
public DateTime ArrivalTime { get; set; }
public bool FullDay { get; set; }
public string Source { get; set; }
public string Comments { get; set; }
public string Origin { get; set; }
public string Destination { get; set; }
public bool IsDisabled { get; set; }
}
}Event Field Settings
Configure field behavior with labels, defaults, and validation:
@using Syncfusion.Blazor.Schedule
<SfSchedule TValue="AppointmentData" Height="550px" @bind-SelectedDate="@CurrentDate">
<ScheduleEventSettings TValue="AppointmentData" DataSource="@DataSource">
<ScheduleField Id="Id">
<FieldSubject Name="Subject" Title="Summary" Default="Add Summary"></FieldSubject>
<FieldLocation Name="Location"></FieldLocation>
<FieldDescription Name="Description"></FieldDescription>
<FieldStartTime Name="StartTime"></FieldStartTime>
<FieldEndTime Name="EndTime"></FieldEndTime>
</ScheduleField>
</ScheduleEventSettings>
<ScheduleViews>
<ScheduleView Option="View.Day"></ScheduleView>
<ScheduleView Option="View.Week"></ScheduleView>
<ScheduleView Option="View.WorkWeek"></ScheduleView>
<ScheduleView Option="View.Month"></ScheduleView>
<ScheduleView Option="View.Agenda"></ScheduleView>
</ScheduleViews>
</SfSchedule>
@code{
DateTime CurrentDate = new DateTime(2020, 1, 31);
List<AppointmentData> DataSource = new List<AppointmentData>
{
new AppointmentData
{
Id = 1,
Subject = "Meeting",
StartTime = new DateTime(2020, 1, 31, 9, 30, 0),
EndTime = new DateTime(2020, 1, 31, 11, 0, 0)
}
};
public class AppointmentData
{
public int Id { get; set; }
public string Subject { get; set; }
public string Location { get; set; }
public DateTime StartTime { get; set; }
public DateTime EndTime { get; set; }
public string Description { get; set; }
public bool IsAllDay { get; set; }
public string RecurrenceRule { get; set; }
public string RecurrenceException { get; set; }
public Nullable<int> RecurrenceID { get; set; }
}
}Field Options:
Default- Default value if not providedName- Maps to dataSource fieldTitle- Label shown in event editorValidation- Validation rules for the field
Adding Custom Fields
Extend appointments with custom properties beyond built-in fields:
@using Syncfusion.Blazor.Schedule
<SfSchedule TValue="AppointmentData" Height="550px" @bind-SelectedDate="@CurrentDate">
<ScheduleEventSettings DataSource="@DataSource"></ScheduleEventSettings>
<ScheduleViews>
<ScheduleView Option="View.Day"></ScheduleView>
<ScheduleView Option="View.Week"></ScheduleView>
<ScheduleView Option="View.Month"></ScheduleView>
</ScheduleViews>
</SfSchedule>
@code{
DateTime CurrentDate = new DateTime(2020, 1, 31);
List<AppointmentData> DataSource = new List<AppointmentData>
{
new AppointmentData
{
Id = 1,
Subject = "Meeting",
StartTime = new DateTime(2020, 1, 31, 9, 30, 0),
EndTime = new DateTime(2020, 1, 31, 11, 0, 0),
Status = "Completed",
Priority = "High"
}
};
public class AppointmentData
{
public int Id { get; set; }
public string Subject { get; set; }
public string Location { get; set; }
public DateTime StartTime { get; set; }
public DateTime EndTime { get; set; }
public string Description { get; set; }
public bool IsAllDay { get; set; }
public string RecurrenceRule { get; set; }
public string RecurrenceException { get; set; }
public Nullable<int> RecurrenceID { get; set; }
// Custom fields - not required to map in EventSettings
public string Status { get; set; }
public string Priority { get; set; }
}
}Custom fields can be accessed in templates and events without explicit field mapping.
Normal Events
Create single-occurrence appointments within a specific time period:
@using Syncfusion.Blazor.Schedule
<SfSchedule TValue="AppointmentData" Height="550px" @bind-SelectedDate="@CurrentDate">
<ScheduleEventSettings DataSource="@DataSource"></ScheduleEventSettings>
<ScheduleViews>
<ScheduleView Option="View.Day"></ScheduleView>
<ScheduleView Option="View.Week"></ScheduleView>
<ScheduleView Option="View.WorkWeek"></ScheduleView>
<ScheduleView Option="View.Month"></ScheduleView>
<ScheduleView Option="View.Agenda"></ScheduleView>
</ScheduleViews>
</SfSchedule>
@code{
DateTime CurrentDate = new DateTime(2020, 1, 31);
List<AppointmentData> DataSource = new List<AppointmentData>
{
new AppointmentData
{
Id = 1,
Subject = "Meeting",
StartTime = new DateTime(2020, 1, 31, 9, 30, 0),
EndTime = new DateTime(2020, 1, 31, 11, 0, 0)
}
};
public class AppointmentData
{
public int Id { get; set; }
public string Subject { get; set; }
public DateTime StartTime { get; set; }
public DateTime EndTime { get; set; }
}
}Spanned Events
Events spanning multiple days (>24 hours) or across day boundaries:
- Multi-day spanned: Appointment created for more than 24 hours, displayed in all-day row
- Cross-day spanned: Appointment created for multiple days but less than 24 hours, split across days
Example: Event from Nov 25 11:00 PM to Nov 26 2:00 AM displays on both days.
All-Day Events
Appointments covering an entire day without specific times. Set IsAllDay = true:
@using Syncfusion.Blazor.Schedule
<SfSchedule TValue="AppointmentData" Height="550px" @bind-SelectedDate="@CurrentDate">
<ScheduleEventSettings DataSource="@DataSource"></ScheduleEventSettings>
<ScheduleViews>
<ScheduleView Option="View.Day"></ScheduleView>
<ScheduleView Option="View.Week"></ScheduleView>
<ScheduleView Option="View.Month"></ScheduleView>
</ScheduleViews>
</SfSchedule>
@code{
DateTime CurrentDate = new DateTime(2023, 1, 31);
List<AppointmentData> DataSource = new List<AppointmentData>
{
new AppointmentData
{
Id = 1,
Subject = "Holiday",
IsAllDay = true,
StartTime = new DateTime(2023, 1, 31, 0, 0, 0),
EndTime = new DateTime(2023, 2, 1, 0, 0, 0)
}
};
public class AppointmentData
{
public int Id { get; set; }
public string Subject { get; set; }
public DateTime StartTime { get; set; }
public DateTime EndTime { get; set; }
public bool IsAllDay { get; set; }
}
}Hide All-Day Row (CSS):
.e-schedule .e-date-header-wrap .e-schedule-table thead {
display: none;
}Block Date and Time
Block specific time slots to prevent event creation. Set IsBlock = true:
@using Syncfusion.Blazor.Schedule
<SfSchedule TValue="AppointmentData" Height="550px" @bind-SelectedDate="@CurrentDate">
<ScheduleEventSettings DataSource="@DataSource"></ScheduleEventSettings>
<ScheduleViews>
<ScheduleView Option="View.Day"></ScheduleView>
<ScheduleView Option="View.Week"></ScheduleView>
<ScheduleView Option="View.WorkWeek"></ScheduleView>
<ScheduleView Option="View.Month"></ScheduleView>
<ScheduleView Option="View.Agenda"></ScheduleView>
</ScheduleViews>
</SfSchedule>
@code{
DateTime CurrentDate = new DateTime(2023, 1, 31);
List<AppointmentData> DataSource = new List<AppointmentData>
{
new AppointmentData
{
Id = 1,
Subject = "Maintenance",
StartTime = new DateTime(2023, 1, 31, 9, 30, 0),
EndTime = new DateTime(2023, 1, 31, 11, 0, 0),
IsBlock = true
}
};
public class AppointmentData
{
public int Id { get; set; }
public string Subject { get; set; }
public DateTime StartTime { get; set; }
public DateTime EndTime { get; set; }
public bool IsBlock { get; set; }
public string RecurrenceRule { get; set; }
public string RecurrenceException { get; set; }
public Nullable<int> RecurrenceID { get; set; }
}
}Recurring Block Events:
new AppointmentData
{
Id = 1,
Subject = "Maintenance",
StartTime = new DateTime(2020, 1, 31, 9, 30, 0),
EndTime = new DateTime(2020, 1, 31, 11, 0, 0),
IsBlock = true,
RecurrenceRule = "FREQ=DAILY;INTERVAL=1;COUNT=5"
}Read-Only Appointments
Prevent CRUD operations on specific appointments.
Disable All Appointments
Use Readonly property on Scheduler:
<SfSchedule TValue="AppointmentData" Height="550px" Readonly="true" @bind-SelectedDate="@CurrentDate">
<ScheduleEventSettings DataSource="DataSource"></ScheduleEventSettings>
<ScheduleViews>
<ScheduleView Option="View.Day"></ScheduleView>
<ScheduleView Option="View.Week"></ScheduleView>
<ScheduleView Option="View.Month"></ScheduleView>
</ScheduleViews>
</SfSchedule>Make Specific Events Read-Only
Set IsReadonly = true on individual appointments:
@using Syncfusion.Blazor.Schedule
<SfSchedule TValue="AppointmentData" Height="550px" @bind-SelectedDate="@CurrentDate">
<ScheduleEventSettings DataSource="DataSource"></ScheduleEventSettings>
<ScheduleViews>
<ScheduleView Option="View.Day"></ScheduleView>
<ScheduleView Option="View.Week"></ScheduleView>
<ScheduleView Option="View.Month"></ScheduleView>
</ScheduleViews>
</SfSchedule>
@code{
DateTime CurrentDate = new DateTime(2020, 1, 31);
List<AppointmentData> DataSource = new List<AppointmentData>
{
new AppointmentData
{
Id = 1,
Subject = "Paris",
StartTime = new DateTime(2020, 1, 28, 10, 0, 0),
EndTime = new DateTime(2020, 1, 28, 12, 0, 0),
IsReadonly = true
},
new AppointmentData
{
Id = 2,
Subject = "Germany",
StartTime = new DateTime(2020, 1, 31, 10, 0, 0),
EndTime = new DateTime(2020, 1, 31, 12, 0, 0)
}
};
public class AppointmentData
{
public int Id { get; set; }
public string Subject { get; set; }
public DateTime StartTime { get; set; }
public DateTime EndTime { get; set; }
public bool IsReadonly { get; set; }
public string RecurrenceRule { get; set; }
public string RecurrenceException { get; set; }
public Nullable<int> RecurrenceID { get; set; }
}
}Read-only events prevent the event editor from opening.
Overlapping Events
Customize Overlapping Order
Sort overlapping events using custom fields:
@using Syncfusion.Blazor.Schedule
<SfSchedule TValue="AppointmentSortData" Width="100%" EnableAutoRowHeight="true" @bind-SelectedDate="@CurrentDate" @bind-CurrentView="@SelectedView">
<ScheduleEventSettings SortBy="RankId" DataSource="@DataSource"></ScheduleEventSettings>
<ScheduleViews>
<ScheduleView Option="View.Day"></ScheduleView>
<ScheduleView Option="View.Week"></ScheduleView>
<ScheduleView Option="View.WorkWeek"></ScheduleView>
<ScheduleView Option="View.Month"></ScheduleView>
<ScheduleView Option="View.TimelineDay"></ScheduleView>
<ScheduleView Option="View.TimelineWeek"></ScheduleView>
<ScheduleView Option="View.TimelineWorkWeek"></ScheduleView>
<ScheduleView Option="View.TimelineMonth"></ScheduleView>
</ScheduleViews>
</SfSchedule>
@code{
DateTime CurrentDate = new DateTime(2023, 2, 14);
View SelectedView = View.Week;
List<AppointmentSortData> DataSource = new List<AppointmentSortData>
{
new AppointmentSortData
{
Id = 1,
Subject = "Rank A",
RankId = "A",
StartTime = new DateTime(2023, 2, 13, 10, 0, 0),
EndTime = new DateTime(2023, 2, 13, 12, 0, 0)
},
new AppointmentSortData
{
Id = 2,
Subject = "Rank B",
RankId = "B",
StartTime = new DateTime(2023, 2, 13, 7, 0, 0),
EndTime = new DateTime(2023, 2, 13, 15, 0, 0)
}
};
public class AppointmentSortData
{
public int Id { get; set; }
public string Subject { get; set; }
public DateTime StartTime { get; set; }
public DateTime EndTime { get; set; }
public string RankId { get; set; }
}
}Prevent Overlapping Events
Block overlapping appointments with AllowOverlap="false":
@using Syncfusion.Blazor.Schedule
<SfSchedule TValue="AppointmentData" AllowOverlap="false" Height="550px" @bind-SelectedDate="@CurrentDate">
<ScheduleEventSettings DataSource="@DataSource"></ScheduleEventSettings>
<ScheduleViews>
<ScheduleView Option="View.Day"></ScheduleView>
<ScheduleView Option="View.Week"></ScheduleView>
<ScheduleView Option="View.Month"></ScheduleView>
</ScheduleViews>
</SfSchedule>
@code {
DateTime CurrentDate = new DateTime(2024, 12, 2);
List<AppointmentData> DataSource = new List<AppointmentData>
{
new AppointmentData
{
Id = 1,
Subject = "Board Meeting",
StartTime = new DateTime(2024, 12, 1, 9, 30, 0),
EndTime = new DateTime(2024, 12, 1, 11, 0, 0)
},
new AppointmentData
{
Id = 2,
Subject = "Conference",
StartTime = new DateTime(2024, 12, 2, 10, 0, 0),
EndTime = new DateTime(2024, 12, 2, 11, 0, 0)
}
};
public class AppointmentData
{
public int Id { get; set; }
public string Subject { get; set; }
public DateTime StartTime { get; set; }
public DateTime EndTime { get; set; }
public bool IsAllDay { get; set; }
public string RecurrenceRule { get; set; }
public Nullable<int> RecurrenceID { get; set; }
public string RecurrenceException { get; set; }
}
}When AllowOverlap=false:
- Initial load prioritizes non-overlapping events
- Recurring appointments skip conflicting instances
- User actions blocked if overlap detected
- Alert shown to user
Limitation: Overlap check only applies to rendered date range.
Check overlaps across all events using ActionBegin event:
<ScheduleEvents TValue="AppointmentData" OnActionBegin="OnActionBegin"></ScheduleEvents>
@code {
public void OnActionBegin(ActionEventArgs<AppointmentData> args)
{
if (args.ActionType == ActionType.EventCreate || args.ActionType == ActionType.EventChange)
{
// Custom logic to check overlaps across all events
}
}
}Slot Availability
Check if a time slot is available before creating appointments:
@using Syncfusion.Blazor.Schedule
<SfSchedule @ref="ScheduleObj" TValue="AppointmentData" Height="600px" @bind-SelectedDate="@CurrentDate">
<ScheduleEvents TValue="AppointmentData" OnActionBegin="OnActionBegin"></ScheduleEvents>
<ScheduleViews>
<ScheduleView Option="View.Week"></ScheduleView>
</ScheduleViews>
<ScheduleEventSettings DataSource="@DataSource"></ScheduleEventSettings>
</SfSchedule>
@code{
private DateTime CurrentDate = new DateTime(2022, 1, 9);
SfSchedule<AppointmentData> ScheduleObj;
List<AppointmentData> DataSource = new List<AppointmentData>
{
new AppointmentData
{
Id = 1,
Subject = "Meeting",
StartTime = new DateTime(2022, 1, 9, 9, 30, 0),
EndTime = new DateTime(2022, 1, 9, 11, 0, 0),
RecurrenceRule = "FREQ=DAILY;INTERVAL=1;COUNT=5"
}
};
public async Task OnActionBegin(ActionEventArgs<AppointmentData> args)
{
bool availability = true;
if (args.ActionType == ActionType.EventCreate || args.ActionType == ActionType.EventChange)
{
var records = args.AddedRecords ?? args.ChangedRecords;
if(records == null) return;
availability = await ScheduleObj.IsSlotAvailableAsync(records.First());
}
args.Cancel = !availability;
}
public class AppointmentData
{
public int Id { get; set; }
public string Subject { get; set; }
public DateTime StartTime { get; set; }
public DateTime EndTime { get; set; }
public string RecurrenceRule { get; set; }
public Nullable<int> RecurrenceID { get; set; }
public string RecurrenceException { get; set; }
}
}Note: IsSlotAvailableAsync checks only current view's date range, not recurrences beyond it.
Appointment Appearance
Differentiate Past Appointments
Use EventRendered event to apply custom styling:
@using Syncfusion.Blazor.Schedule
<SfSchedule TValue="AppointmentData" Width="100%" Height="550px" @bind-SelectedDate="@SelectedDate">
<ScheduleViews>
<ScheduleView Option="View.Day"></ScheduleView>
<ScheduleView Option="View.Week"></ScheduleView>
<ScheduleView Option="View.Month"></ScheduleView>
</ScheduleViews>
<ScheduleEvents TValue="AppointmentData" EventRendered="OnEventRendered"></ScheduleEvents>
<ScheduleEventSettings DataSource="@DataSource"></ScheduleEventSettings>
</SfSchedule>
@code{
public DateTime SelectedDate = new DateTime(2023, 1, 10);
public List<string> CustomClass = new List<string>() { "e-past-app" };
public void OnEventRendered(EventRenderedArgs<AppointmentData> args)
{
if(args.Data.StartTime < SelectedDate)
{
args.CssClasses = CustomClass;
}
}
List<AppointmentData> DataSource = new List<AppointmentData>
{
new AppointmentData
{
Id = 1,
Subject = "Meeting",
StartTime = new DateTime(2023, 1, 10, 9, 30, 0),
EndTime = new DateTime(2023, 1, 10, 11, 0, 0)
},
new AppointmentData
{
Id = 2,
Subject = "Conference",
StartTime = new DateTime(2023, 1, 9, 11, 30, 0),
EndTime = new DateTime(2023, 1, 9, 13, 0, 0)
}
};
public class AppointmentData
{
public int Id { get; set; }
public string Subject { get; set; }
public DateTime StartTime { get; set; }
public DateTime EndTime { get; set; }
}
}
<style>
.e-schedule .e-vertical-view .e-day-wrapper .e-appointment.e-past-app,
.e-schedule .e-month-view .e-appointment.e-past-app {
background-color: chocolate;
}
</style>Full-Height Appointments
Make appointments occupy entire cell height:
@using Syncfusion.Blazor.Schedule
<SfSchedule TValue="AppointmentData" Width="100%" Height="550px" SelectedDate="@(new DateTime(2023, 3, 11))" CurrentView="View.Month">
<ScheduleViews>
<ScheduleView Option="View.Week"></ScheduleView>
<ScheduleView Option="View.Month"></ScheduleView>
<ScheduleView Option="View.TimelineWeek"></ScheduleView>
<ScheduleView Option="View.TimelineMonth"></ScheduleView>
</ScheduleViews>
<ScheduleEventSettings DataSource="@DataSource" EnableMaxHeight="true" EnableIndicator="true"></ScheduleEventSettings>
</SfSchedule>
@code{
List<AppointmentData> DataSource = new List<AppointmentData>
{
new AppointmentData
{
Id = 1,
Subject = "Meeting",
StartTime = new DateTime(2023, 3, 11, 9, 30, 0),
EndTime = new DateTime(2023, 3, 11, 11, 0, 0)
},
new AppointmentData
{
Id = 2,
Subject = "Conference",
StartTime = new DateTime(2023, 3, 11, 9, 30, 0),
EndTime = new DateTime(2023, 3, 11, 11, 0, 0)
}
};
public class AppointmentData
{
public int Id { get; set; }
public string Subject { get; set; }
public DateTime StartTime { get; set; }
public DateTime EndTime { get; set; }
}
}EnableMaxHeight="true"- Appointments occupy full cell heightEnableIndicator="true"- Shows more indicator when multiple appointments in same cell
Tooltips
Enable Built-In Tooltip
@using Syncfusion.Blazor.Schedule
<SfSchedule TValue="AppointmentData" Height="550px" @bind-SelectedDate="@CurrentDate">
<ScheduleEventSettings DataSource="@DataSource" EnableTooltip="true"></ScheduleEventSettings>
<ScheduleViews>
<ScheduleView Option="View.Day"></ScheduleView>
<ScheduleView Option="View.Week"></ScheduleView>
<ScheduleView Option="View.Month"></ScheduleView>
</ScheduleViews>
</SfSchedule>
@code{
DateTime CurrentDate = new DateTime(2023, 1, 10);
List<AppointmentData> DataSource = new List<AppointmentData>
{
new AppointmentData
{
Id = 1,
Subject = "Meeting",
StartTime = new DateTime(2023, 1, 8, 10, 0, 0),
EndTime = new DateTime(2023, 1, 8, 12, 0, 0)
}
};
public class AppointmentData
{
public int Id { get; set; }
public string Subject { get; set; }
public DateTime StartTime { get; set; }
public DateTime EndTime { get; set; }
}
}Customize Tooltip Template
@using Syncfusion.Blazor.Schedule
<SfSchedule TValue="AppointmentData" Height="550px" @bind-SelectedDate="@CurrentDate">
<ScheduleEventSettings DataSource="@DataSource" EnableTooltip="true">
<TooltipTemplate>
<div class="tooltip-wrap">
<div>@((context as AppointmentData).Subject)</div>
<div>From: @((context as AppointmentData).StartTime)</div>
<div>To: @((context as AppointmentData).EndTime)</div>
</div>
</TooltipTemplate>
</ScheduleEventSettings>
<ScheduleViews>
<ScheduleView Option="View.Day"></ScheduleView>
<ScheduleView Option="View.Week"></ScheduleView>
<ScheduleView Option="View.Month"></ScheduleView>
</ScheduleViews>
</SfSchedule>
@code{
DateTime CurrentDate = new DateTime(2023, 1, 13);
List<AppointmentData> DataSource = new List<AppointmentData>
{
new AppointmentData
{
Id = 1,
Subject = "Meeting",
StartTime = new DateTime(2023, 1, 11, 10, 0, 0),
EndTime = new DateTime(2023, 1, 11, 12, 0, 0)
}
};
public class AppointmentData
{
public int Id { get; set; }
public string Subject { get; set; }
public DateTime StartTime { get; set; }
public DateTime EndTime { get; set; }
}
}Prevent Tooltip for Specific Events
@using Syncfusion.Blazor.Schedule
<SfSchedule TValue="AppointmentData" Height="550px" @bind-SelectedDate="@CurrentDate">
<ScheduleEvents TValue="AppointmentData" TooltipOpening="OnTooltipOpening"></ScheduleEvents>
<ScheduleEventSettings DataSource="@DataSource" EnableTooltip="true"></ScheduleEventSettings>
<ScheduleViews>
<ScheduleView Option="View.Month"></ScheduleView>
</ScheduleViews>
</SfSchedule>
@code {
DateTime CurrentDate = new DateTime(2025, 1, 10);
List<AppointmentData> DataSource = new List<AppointmentData>
{
new AppointmentData
{
Id = 1,
Subject = "Meeting",
StartTime = new DateTime(2025, 1, 8, 10, 0, 0),
EndTime = new DateTime(2025, 1, 8, 12, 0, 0)
},
new AppointmentData
{
Id = 2,
Subject = "Vacation",
StartTime = new DateTime(2025, 1, 10, 10, 0, 0),
EndTime = new DateTime(2025, 1, 10, 12, 0, 0)
}
};
public void OnTooltipOpening(TooltipOpenEventArgs<AppointmentData> args)
{
if(args.Data.Subject == "Vacation")
{
args.Cancel = true;
}
}
public class AppointmentData
{
public int Id { get; set; }
public string Subject { get; set; }
public DateTime StartTime { get; set; }
public DateTime EndTime { get; set; }
}
}Appointment Selection
Select appointments using mouse or keyboard:
| Action | Behavior |
|---|---|
| Click/Tap appointment | Select single appointment |
| Ctrl + Click/Tap | Select multiple appointments |
| Delete key | Delete selected appointment(s) |
Deleting multiple occurrences from a series only deletes those occurrences, not the entire series.
Retrieving Appointments
Get Target Event from Coordinates
await ScheduleObj.GetTargetEventAsync(x, y);Get Selected Appointments
await ScheduleObj.GetSelectedEventsAsync();Get Current View Appointments
<SfSchedule TValue="AppointmentData" @ref="ScheduleRef" Width="100%" Height="550px" @bind-SelectedDate="@CurrentDate">
<ScheduleEvents TValue="AppointmentData" DataBound="OnDataBound"></ScheduleEvents>
<ScheduleEventSettings DataSource="@DataSource"></ScheduleEventSettings>
<ScheduleViews>
<ScheduleView Option="View.Month"></ScheduleView>
</ScheduleViews>
</SfSchedule>
@code{
DateTime CurrentDate = new DateTime(2020, 1, 10);
SfSchedule<AppointmentData> ScheduleRef;
public void OnDataBound(DataBoundEventArgs<AppointmentData> args)
{
List<AppointmentData> eventCollection = ScheduleRef.GetCurrentViewEvents();
}
List<AppointmentData> DataSource = new List<AppointmentData>
{
new AppointmentData
{
Id = 1,
Subject = "Meeting",
StartTime = new DateTime(2020, 1, 10, 9, 30, 0),
EndTime = new DateTime(2020, 1, 10, 11, 30, 0)
}
};
public class AppointmentData
{
public int Id { get; set; }
public string Subject { get; set; }
public DateTime StartTime { get; set; }
public DateTime EndTime { get; set; }
}
}Get All Appointments
<SfSchedule TValue="AppointmentData" @ref="ScheduleRef" Width="100%" Height="550px" SelectedDate="@(new DateTime(2020,1,10))">
<ScheduleEvents TValue="AppointmentData" DataBound="OnDataBound"></ScheduleEvents>
<ScheduleEventSettings DataSource="@DataSource"></ScheduleEventSettings>
</SfSchedule>
@code{
SfSchedule<AppointmentData> ScheduleRef;
public async void OnDataBound(DataBoundEventArgs<AppointmentData> args)
{
List<AppointmentData> EventCollection = await ScheduleRef.GetEventsAsync();
}
List<AppointmentData> DataSource = new List<AppointmentData>
{
new AppointmentData
{
Id = 1,
Subject = "Meeting",
StartTime = new DateTime(2020, 1, 10, 9, 30, 0),
EndTime = new DateTime(2020, 1, 10, 11, 30, 0)
}
};
public class AppointmentData
{
public int Id { get; set; }
public string Subject { get; set; }
public DateTime StartTime { get; set; }
public DateTime EndTime { get; set; }
}
}Pass date range to `GetEventsAsync()`:
await ScheduleRef.GetEventsAsync(startDate, endDate);Get block events:
await ScheduleRef.GetBlockEventsAsync();Filtering Appointments
Filter appointments by specific criteria:
@using Syncfusion.Blazor.Schedule
@using Syncfusion.Blazor.Data
@using Syncfusion.Blazor.Buttons
<SfCheckBox TChecked="bool" @bind-Checked="MargretChecked" Value="@MargretId" ValueChange="@OnChange" Label="Margaret"></SfCheckBox>
<SfCheckBox TChecked="bool" @bind-Checked="RobertChecked" Value="@RobertId" ValueChange="@OnChange" Label="Robert"></SfCheckBox>
<SfSchedule TValue="AppointmentData" Width="100%" Height="650px" @bind-SelectedDate="@CurrentDate">
<ScheduleEventSettings DataSource="@DataSource" Query="@ScheduleQuery"></ScheduleEventSettings>
<ScheduleViews>
<ScheduleView Option="View.Month"></ScheduleView>
</ScheduleViews>
</SfSchedule>
@code{
public DateTime CurrentDate { get; set; } = new DateTime(2020, 6, 5);
public bool MargretChecked { get; set; } = true;
public bool RobertChecked { get; set; } = true;
public dynamic predicate;
public Query ScheduleQuery { get; set; } = null;
List<AppointmentData> DataSource = new List<AppointmentData>
{
new AppointmentData
{
Id = 1,
Subject = "Event 1",
StartTime = new DateTime(2020, 5, 29, 15, 0, 0),
EndTime = new DateTime(2020, 5, 29, 17, 0, 0),
OwnerId = 1
}
};
public void OnChange(ChangeEventArgs<bool> args)
{
predicate = null;
if (MargretChecked)
{
predicate = new WhereFilter() { Field = "OwnerId", Operator = "equal", value = 1 };
}
if (RobertChecked)
{
if (predicate != null)
{
predicate = predicate.Or("OwnerId", "equal", 2);
}
}
ScheduleQuery = new Query().Where(predicate);
}
public class AppointmentData
{
public int Id { get; set; }
public string Subject { get; set; }
public DateTime StartTime { get; set; }
public DateTime EndTime { get; set; }
public int OwnerId { get; set; }
}
}Refresh Appointments
Refresh appointment collection without reloading Scheduler:
await ScheduleRef.RefreshEventsAsync();This updates appointments from the data source without full Scheduler refresh.
Cell Customization
Table of Contents
- Overview
- Setting Cell Dimensions
- Customizing Cells with CellTemplate
- Cell Header Template
- OnRenderCell Event
- Weekend Cell Customization
- Min and Max Date Customization
- Disabling Multiple Cell Selection
Overview
Customize Scheduler cells using CellTemplate, CellHeaderTemplate, and the OnRenderCell event. These approaches allow you to modify cell appearance, add custom content, and apply conditional styling based on date, time, or other criteria.
Setting Cell Dimensions
Vertical Views Cell Dimensions
Customize cell width and height in Day, Week, and Work Week views using CssClass:
@using Syncfusion.Blazor.Schedule
<SfSchedule TValue="AppointmentData" CssClass="schedule-cell-dimension" Height="550px">
<ScheduleViews>
<ScheduleView Option="View.Day"></ScheduleView>
<ScheduleView Option="View.Week"></ScheduleView>
<ScheduleView Option="View.WorkWeek"></ScheduleView>
<ScheduleView Option="View.Month"></ScheduleView>
</ScheduleViews>
</SfSchedule>
<style>
.schedule-cell-dimension.e-schedule .e-vertical-view .e-date-header-wrap table col,
.schedule-cell-dimension.e-schedule .e-vertical-view .e-content-wrap table col {
width: 200px;
}
.schedule-cell-dimension.e-schedule .e-vertical-view .e-time-cells-wrap table td,
.schedule-cell-dimension.e-schedule .e-vertical-view .e-work-cells {
height: 100px;
}
.schedule-cell-dimension.e-schedule .e-month-view .e-work-cells,
.schedule-cell-dimension.e-schedule .e-month-view .e-date-header-wrap table col {
width: 200px;
}
.schedule-cell-dimension.e-schedule .e-month-view .e-work-cells {
height: 200px;
}
</style>
@code{
public class AppointmentData
{
public int Id { get; set; }
public string Subject { get; set; }
public DateTime StartTime { get; set; }
public DateTime EndTime { get; set; }
}
}Timeline Views Cell Dimensions
Customize Timeline view cell dimensions:
@using Syncfusion.Blazor.Schedule
<SfSchedule TValue="AppointmentData" CssClass="schedule-cell-dimension" Height="550px">
<ScheduleViews>
<ScheduleView Option="View.TimelineWeek" MaxEventsPerRow="10"></ScheduleView>
<ScheduleView Option="View.TimelineMonth" MaxEventsPerRow="10"></ScheduleView>
</ScheduleViews>
</SfSchedule>
<style>
.schedule-cell-dimension.e-schedule .e-timeline-view .e-date-header-wrap table col,
.schedule-cell-dimension.e-schedule .e-timeline-view .e-content-wrap table col {
width: 200px;
}
.schedule-cell-dimension.e-schedule .e-timeline-month-view .e-date-header-wrap table col,
.schedule-cell-dimension.e-schedule .e-timeline-month-view .e-content-wrap table col {
width: 200px;
}
</style>
@code{
public class AppointmentData
{
public int Id { get; set; }
public string Subject { get; set; }
public DateTime StartTime { get; set; }
public DateTime EndTime { get; set; }
}
}Customizing Cells with CellTemplate
The CellTemplate allows you to customize cell background with specific images, text, or custom content on given date values:
@using Syncfusion.Blazor.Schedule
<SfSchedule TValue="AppointmentData" Width="100%" Height="650px" @bind-SelectedDate="@CurrentDate">
<ScheduleTemplates>
<CellTemplate>
<div class="templatewrap">
@{
@if ((int)(context as TemplateContext).Date.Month == 3 && (int)(context as TemplateContext).Date.Day == 24)
{
<div class="caption">Team Meeting</div>
}
@if ((int)(context as TemplateContext).Date.Month == 3 && (int)(context as TemplateContext).Date.Day == 25)
{
<div class="caption">Project Deadline</div>
}
@if ((int)(context as TemplateContext).Date.Month == 3 && (int)(context as TemplateContext).Date.Day == 26)
{
<div class="caption">Training Day</div>
}
}
</div>
</CellTemplate>
</ScheduleTemplates>
<ScheduleViews>
<ScheduleView Option="View.Month" MaxEventsPerRow="2"></ScheduleView>
</ScheduleViews>
</SfSchedule>
<style>
.e-schedule .e-month-view .e-work-cells {
position: relative;
}
.e-schedule .templatewrap {
text-align: center;
position: absolute;
width: 100%;
}
.e-schedule .caption {
overflow: hidden;
text-overflow: ellipsis;
vertical-align: middle;
font-weight: bold;
color: #d9534f;
}
</style>
@code {
DateTime CurrentDate = new DateTime(2026, 3, 24);
public class AppointmentData
{
public int Id { get; set; }
public string Subject { get; set; }
public DateTime StartTime { get; set; }
public DateTime EndTime { get; set; }
}
}Cell Header Template
Customize the month header of each date cell using CellHeaderTemplate:
@using Syncfusion.Blazor.Schedule
@using System.Globalization
<SfSchedule TValue="AppointmentData" Width="100%" Height="650px" @bind-SelectedDate="@CurrentDate">
<ScheduleTemplates>
<CellHeaderTemplate>
<div>@context.Date.ToString("dd ddd", CultureInfo.InvariantCulture)</div>
</CellHeaderTemplate>
</ScheduleTemplates>
<ScheduleEventSettings DataSource="@DataSource"></ScheduleEventSettings>
<ScheduleViews>
<ScheduleView Option="View.Month"></ScheduleView>
</ScheduleViews>
</SfSchedule>
@code {
DateTime CurrentDate = new DateTime(2026, 3, 24);
List<AppointmentData> DataSource = new List<AppointmentData>
{
new AppointmentData
{
Id = 1,
Subject = "Meeting",
StartTime = new DateTime(2026, 3, 24, 9, 30, 0),
EndTime = new DateTime(2026, 3, 24, 11, 0, 0),
RecurrenceRule = "FREQ=DAILY;INTERVAL=1;COUNT=5"
}
};
public class AppointmentData
{
public int Id { get; set; }
public string Subject { get; set; }
public DateTime StartTime { get; set; }
public DateTime EndTime { get; set; }
public bool IsAllDay { get; set; }
public string RecurrenceRule { get; set; }
public Nullable<int> RecurrenceID { get; set; }
public string RecurrenceException { get; set; }
}
}OnRenderCell Event
Customize cells using the OnRenderCell event. This event fires for each cell during rendering and provides access to RenderCellEventArgs with ElementType property:
@using Syncfusion.Blazor.Schedule
<SfSchedule TValue="AppointmentData" Width="100%" Height="550px" @bind-SelectedDate="@CurrentDate">
<ScheduleEvents TValue="AppointmentData" OnRenderCell="OnRenderCell"></ScheduleEvents>
<ScheduleEventSettings DataSource="@DataSource"></ScheduleEventSettings>
<ScheduleViews>
<ScheduleView Option="View.Day"></ScheduleView>
<ScheduleView Option="View.Week"></ScheduleView>
<ScheduleView Option="View.WorkWeek"></ScheduleView>
<ScheduleView Option="View.Month"></ScheduleView>
</ScheduleViews>
</SfSchedule>
<style>
.e-schedule .e-vertical-view .e-work-hours.custom-class {
background-color: ivory;
}
</style>
@code{
DateTime CurrentDate = new DateTime(2026, 3, 24);
public string[] CustomClass = { "custom-class" };
public void OnRenderCell(RenderCellEventArgs args)
{
// Customize cells based on ElementType
if (args.ElementType == ElementType.WorkCells)
{
args.CssClasses = new List<string>(CustomClass);
}
}
List<AppointmentData> DataSource = new List<AppointmentData>
{
new AppointmentData
{
Id = 1,
Subject = "Meeting",
StartTime = new DateTime(2026, 3, 24, 9, 30, 0),
EndTime = new DateTime(2026, 3, 24, 12, 0, 0)
}
};
public class AppointmentData
{
public int Id { get; set; }
public string Subject { get; set; }
public DateTime StartTime { get; set; }
public DateTime EndTime { get; set; }
}
}Weekend Cell Customization
Customize the background color of weekend cells using OnRenderCell event and CssClasses:
@using Syncfusion.Blazor.Schedule
<SfSchedule TValue="AppointmentData" Width="100%" Height="550px" @bind-SelectedDate="@CurrentDate" CssClass="schedule-cell-customization">
<ScheduleEvents TValue="AppointmentData" OnRenderCell="OnRenderCell"></ScheduleEvents>
<ScheduleEventSettings DataSource="@DataSource"></ScheduleEventSettings>
<ScheduleViews>
<ScheduleView Option="View.Day"></ScheduleView>
<ScheduleView Option="View.Week"></ScheduleView>
<ScheduleView Option="View.WorkWeek"></ScheduleView>
<ScheduleView Option="View.Month"></ScheduleView>
</ScheduleViews>
</SfSchedule>
<style>
.schedule-cell-customization.e-schedule .e-vertical-view .e-work-cells.weekend-class {
background-color: #ffdea2;
}
.schedule-cell-customization.e-schedule .e-month-view .e-work-cells:not(.e-work-days) {
background-color: #f08080;
}
</style>
@code {
DateTime CurrentDate = new DateTime(2026, 3, 24);
public string[] WeekendClass = { "weekend-class" };
public void OnRenderCell(RenderCellEventArgs args)
{
// Check if the date is weekend
if (args.ElementType == ElementType.WorkCells)
{
if (args.Date.DayOfWeek == DayOfWeek.Sunday || args.Date.DayOfWeek == DayOfWeek.Saturday)
{
args.CssClasses = new List<string>(WeekendClass);
}
}
}
List<AppointmentData> DataSource = new List<AppointmentData>
{
new AppointmentData
{
Id = 1,
Subject = "Meeting",
StartTime = new DateTime(2026, 3, 24, 9, 30, 0),
EndTime = new DateTime(2026, 3, 24, 12, 0, 0)
}
};
public class AppointmentData
{
public int Id { get; set; }
public string Subject { get; set; }
public DateTime StartTime { get; set; }
public DateTime EndTime { get; set; }
}
}Min and Max Date Customization
Restrict date range by setting MinDate and MaxDate properties. Dates outside this range will be disabled and navigation will be blocked:
@using Syncfusion.Blazor.Schedule
<SfSchedule TValue="AppointmentData"
Height="650px"
MinDate="new DateTime(2026, 3, 1)"
MaxDate="new DateTime(2026, 3, 31)"
@bind-SelectedDate="@CurrentDate">
<ScheduleViews>
<ScheduleView Option="View.Day"></ScheduleView>
<ScheduleView Option="View.Week"></ScheduleView>
<ScheduleView Option="View.WorkWeek"></ScheduleView>
<ScheduleView Option="View.Month"></ScheduleView>
</ScheduleViews>
</SfSchedule>
@code{
DateTime CurrentDate = new DateTime(2026, 3, 24);
public class AppointmentData
{
public int Id { get; set; }
public string Subject { get; set; }
public DateTime StartTime { get; set; }
public DateTime EndTime { get; set; }
}
}Disabling Multiple Cell Selection
By default, AllowMultiCellSelection and AllowMultiRowSelection properties are enabled. Disable them to prevent multiple cell/row selection:
@using Syncfusion.Blazor.Schedule
<SfSchedule TValue="AppointmentData"
Height="550px"
AllowMultiCellSelection="false"
AllowMultiRowSelection="false"
@bind-SelectedDate="@CurrentDate">
<ScheduleViews>
<ScheduleView Option="View.Day"></ScheduleView>
<ScheduleView Option="View.Week"></ScheduleView>
<ScheduleView Option="View.WorkWeek"></ScheduleView>
<ScheduleView Option="View.Month"></ScheduleView>
</ScheduleViews>
</SfSchedule>
@code{
DateTime CurrentDate = new DateTime(2026, 3, 24);
public class AppointmentData
{
public int Id { get; set; }
public string Subject { get; set; }
public DateTime StartTime { get; set; }
public DateTime EndTime { get; set; }
}
}Common Patterns
CellTemplate vs OnRenderCell:
- Use CellTemplate for adding custom HTML content or images to cells
- Use OnRenderCell for applying CSS classes and styling based on conditions
Applying Styles:
- Use CssClass property on SfSchedule for global cell styling
- Use OnRenderCell with CssClasses for conditional styling
- Use
<style>tags with selector chains like.custom-class.e-schedule .e-work-cells
ElementType Values:
ElementType.WorkCells: Regular time slot cells in vertical/timeline viewsElementType.AllDayCells: All-day event row cellsElementType.MonthCells: Month view date cells
Clipboard Operations
Table of Contents
- Overview
- Enabling Clipboard Feature
- Keyboard Shortcuts
- Copy, Cut, Paste with Keyboard
- Context Menu Integration
- Programmatic Methods
- Modifying Content Before Pasting
- Grid to Scheduler Clipboard Integration
Overview
The Clipboard functionality in Syncfusion Scheduler enables users to cut, copy, and paste appointments efficiently. This feature eliminates repetitive data entry and allows quick schedule adjustments. The feature can be used via keyboard shortcuts or programmatically through public methods like CopyAsync(), CutAsync(), and PasteAsync().
Enabling Clipboard Feature
To activate clipboard functionality, set the AllowClipboard property to true. The AllowKeyboardInteraction property must also be enabled for proper keyboard shortcut functionality:
@using Syncfusion.Blazor.Schedule
<SfSchedule TValue="AppointmentData"
Height="650px"
@bind-SelectedDate="@SelectedDate"
AllowClipboard="true"
AllowKeyboardInteraction="true"
ShowQuickInfo="false">
<ScheduleEventSettings DataSource="@DataSource"></ScheduleEventSettings>
<ScheduleViews>
<ScheduleView Option="View.Day"></ScheduleView>
<ScheduleView Option="View.Week"></ScheduleView>
<ScheduleView Option="View.WorkWeek"></ScheduleView>
<ScheduleView Option="View.Month"></ScheduleView>
<ScheduleView Option="View.Agenda"></ScheduleView>
</ScheduleViews>
</SfSchedule>
@code {
private DateTime SelectedDate { get; set; } = new DateTime(2026, 3, 24);
public List<AppointmentData> DataSource = new List<AppointmentData>
{
new AppointmentData
{
Id = 1,
Subject = "Meeting with clients",
StartTime = new DateTime(2026, 3, 24, 9, 30, 0),
EndTime = new DateTime(2026, 3, 24, 11, 0, 0),
IsAllDay = false
},
new AppointmentData
{
Id = 2,
Subject = "Project Review",
StartTime = new DateTime(2026, 3, 24, 12, 0, 0),
EndTime = new DateTime(2026, 3, 24, 14, 0, 0),
IsAllDay = false
},
new AppointmentData
{
Id = 3,
Subject = "Team Lunch",
StartTime = new DateTime(2026, 3, 25, 12, 0, 0),
EndTime = new DateTime(2026, 3, 25, 13, 0, 0),
IsAllDay = false
}
};
public class AppointmentData
{
public int Id { get; set; }
public string Subject { get; set; }
public string Location { get; set; }
public DateTime StartTime { get; set; }
public DateTime EndTime { get; set; }
public string Description { get; set; }
public bool IsAllDay { get; set; }
public string RecurrenceRule { get; set; }
public string RecurrenceException { get; set; }
public Nullable<int> RecurrenceID { get; set; }
}
}Keyboard Shortcuts
The Syncfusion Scheduler supports standard keyboard shortcuts for clipboard operations:
| Operation | Keyboard Shortcut | Mac Alternative | Description |
|---|---|---|---|
| Copy | Ctrl+C | Cmd+C | Duplicate selected appointment |
| Cut | Ctrl+X | Cmd+X | Move selected appointment to clipboard |
| Paste | Ctrl+V | Cmd+V | Insert clipboard appointment into selected time slot |
Copy, Cut, Paste with Keyboard
To use keyboard shortcuts:
1. Copy an appointment: Click on the appointment → Press Ctrl+C 2. Cut an appointment: Click on the appointment → Press Ctrl+X 3. Paste an appointment: Click on desired time slot → Press Ctrl+V
For Mac users, replace Ctrl with Cmd.
Example with keyboard interaction enabled:
@using Syncfusion.Blazor.Schedule
<SfSchedule TValue="AppointmentData"
Height="650px"
@bind-SelectedDate="@SelectedDate"
AllowClipboard="true"
AllowKeyboardInteraction="true"
ShowQuickInfo="false">
<ScheduleEventSettings DataSource="@DataSource"></ScheduleEventSettings>
<ScheduleViews>
<ScheduleView Option="View.Day"></ScheduleView>
<ScheduleView Option="View.Week"></ScheduleView>
<ScheduleView Option="View.WorkWeek"></ScheduleView>
<ScheduleView Option="View.Month"></ScheduleView>
</ScheduleViews>
</SfSchedule>
@code {
private DateTime SelectedDate { get; set; } = new DateTime(2026, 3, 24);
public List<AppointmentData> DataSource = new List<AppointmentData>
{
new AppointmentData
{
Id = 1,
Subject = "Meeting with clients",
StartTime = new DateTime(2026, 3, 24, 9, 30, 0),
EndTime = new DateTime(2026, 3, 24, 11, 0, 0)
},
new AppointmentData
{
Id = 2,
Subject = "Project Review",
StartTime = new DateTime(2026, 3, 24, 12, 0, 0),
EndTime = new DateTime(2026, 3, 24, 14, 0, 0)
},
new AppointmentData
{
Id = 3,
Subject = "Status Update",
StartTime = new DateTime(2026, 3, 25, 15, 0, 0),
EndTime = new DateTime(2026, 3, 25, 16, 30, 0)
}
};
public class AppointmentData
{
public int Id { get; set; }
public string Subject { get; set; }
public string Location { get; set; }
public DateTime StartTime { get; set; }
public DateTime EndTime { get; set; }
public string Description { get; set; }
public bool IsAllDay { get; set; }
public string RecurrenceRule { get; set; }
public string RecurrenceException { get; set; }
public Nullable<int> RecurrenceID { get; set; }
}
}Context Menu Integration
Use context menus with CopyAsync(), CutAsync(), and PasteAsync() methods to provide clipboard operations programmatically:
@using Syncfusion.Blazor.Schedule
@using Syncfusion.Blazor.Navigations
<div class="col-lg-12 control-section">
<SfSchedule TValue="AppointmentData" @ref="ScheduleRef"
Height="650px"
@bind-SelectedDate="@SelectedDate"
AllowClipboard="true"
ShowQuickInfo="false">
<ScheduleEventSettings DataSource="@EventDataSource"></ScheduleEventSettings>
<ScheduleViews>
<ScheduleView Option="View.Week"></ScheduleView>
<ScheduleView Option="View.Day"></ScheduleView>
<ScheduleView Option="View.Month"></ScheduleView>
</ScheduleViews>
</SfSchedule>
<SfContextMenu TValue="MenuItem" Target=".e-schedule">
<MenuItems>
<MenuItem Text="Copy" Id="Copy" Hidden="@(!isEvent)" IconCss="e-icons e-copy"></MenuItem>
<MenuItem Text="Cut" Id="Cut" Hidden="@(!isEvent)" IconCss="e-icons e-cut"></MenuItem>
<MenuItem Text="Paste" Id="Paste" Hidden="@(!isCell)" IconCss="e-icons e-paste"></MenuItem>
</MenuItems>
<MenuEvents TValue="MenuItem" OnOpen="OnOpen" ItemSelected="OnItemSelected"></MenuEvents>
</SfContextMenu>
</div>
@code {
private DateTime SelectedDate { get; set; } = new DateTime(2026, 3, 24);
private bool isCell;
private bool isEvent;
SfSchedule<AppointmentData> ScheduleRef;
private AppointmentData EventData { get; set; }
private CellClickEventArgs CellData { get; set; }
private ElementInfo<AppointmentData> ElementData { get; set; }
private List<AppointmentData> EventDataSource = new List<AppointmentData>()
{
new AppointmentData
{
Id = 1,
Subject = "Explosion of Betelgeuse Star",
Location = "Space Centre USA",
StartTime = new DateTime(2026, 3, 24, 9, 30, 0),
EndTime = new DateTime(2026, 3, 24, 11, 0, 0),
CategoryColor = "#1aaa55"
},
new AppointmentData
{
Id = 2,
Subject = "Thule Air Crash Report",
Location = "New York City",
StartTime = new DateTime(2026, 3, 25, 12, 0, 0),
EndTime = new DateTime(2026, 3, 25, 14, 0, 0),
CategoryColor = "#357cd2"
},
new AppointmentData
{
Id = 3,
Subject = "Blue Moon Eclipse",
Location = "Space Centre USA",
StartTime = new DateTime(2026, 3, 26, 9, 30, 0),
EndTime = new DateTime(2026, 3, 26, 11, 0, 0),
CategoryColor = "#7fa900"
}
};
public async Task OnOpen(BeforeOpenCloseMenuEventArgs<MenuItem> args)
{
ElementData = await ScheduleRef.GetElementInfoAsync((int)args.Left, (int)args.Top);
if (args.ParentItem == null && ElementData != null)
{
if (ElementData.ElementType == ElementType.Event)
{
EventData = ElementData.EventData;
isCell = false;
isEvent = true;
}
else if (ElementData.ElementType == ElementType.WorkCells || ElementData.ElementType == ElementType.DateHeader ||
ElementData.ElementType == ElementType.AllDayCells)
{
isCell = true;
isEvent = false;
CellData = new CellClickEventArgs
{
StartTime = ElementData.StartTime,
EndTime = ElementData.EndTime,
IsAllDay = ElementData.IsAllDay
};
}
else
{
args.Cancel = true;
}
}
}
public async Task OnItemSelected(MenuEventArgs<MenuItem> args)
{
var SelectedMenuItem = args.Item.Id;
switch (SelectedMenuItem)
{
case "Copy":
await CopyEvent(EventData);
break;
case "Cut":
await CutEvent(EventData);
break;
case "Paste":
if (isCell)
{
await PasteEvent(CellData);
}
break;
}
}
private async Task PasteEvent(CellClickEventArgs cellData)
{
await ScheduleRef.PasteAsync(cellData);
}
private async Task CopyEvent(AppointmentData eventData)
{
await ScheduleRef.CopyAsync(eventData);
}
private async Task CutEvent(AppointmentData eventData)
{
await ScheduleRef.CutAsync(eventData);
}
public class AppointmentData
{
public int Id { get; set; }
public string Subject { get; set; }
public string Location { get; set; }
public string Description { get; set; }
public DateTime StartTime { get; set; }
public DateTime EndTime { get; set; }
public Nullable<bool> IsAllDay { get; set; }
public string CategoryColor { get; set; }
public string RecurrenceRule { get; set; }
public Nullable<int> RecurrenceID { get; set; }
public string RecurrenceException { get; set; }
}
}Programmatic Methods
Use these public methods to manage clipboard operations programmatically:
| Method | Parameters | Description |
|---|---|---|
CopyAsync() | None | Duplicate the selected appointment for reuse |
CutAsync() | None | Remove the selected appointment for moving |
PasteAsync(CellClickEventArgs) | targetElement | Insert clipboard appointment into specified time slot |
Modifying Content Before Pasting
Use the Paste event to intercept and modify appointment details before they are pasted into the scheduler:
@using Syncfusion.Blazor.Schedule
@using Syncfusion.Blazor.Grids
<div class="container">
<div class="row">
<div class="col-lg-6">
<SfSchedule TValue="AppointmentData" @ref="ScheduleRef"
Height="550px"
Width="100%"
@bind-SelectedDate="@CurrentDate"
AllowClipboard="true"
ShowQuickInfo="false">
<ScheduleEvents TValue="AppointmentData" Paste="OnBeforePaste"></ScheduleEvents>
<ScheduleEventSettings DataSource="@ScheduleData"></ScheduleEventSettings>
<ScheduleViews>
<ScheduleView Option="View.Day"></ScheduleView>
<ScheduleView Option="View.Week"></ScheduleView>
<ScheduleView Option="View.WorkWeek"></ScheduleView>
<ScheduleView Option="View.Month"></ScheduleView>
</ScheduleViews>
</SfSchedule>
</div>
<div class="col-lg-6">
<SfGrid @ref="GridRef" DataSource="@GridData" AllowSelection="true" Width="100%">
<GridColumns>
<GridColumn Field="OrderID" HeaderText="Order ID" Width="90" TextAlign="TextAlign.Right"></GridColumn>
<GridColumn Field="CustomerID" HeaderText="Customer ID" Width="100"></GridColumn>
<GridColumn Field="ShipCity" HeaderText="Ship City" Width="100"></GridColumn>
<GridColumn Field="ShipName" HeaderText="Ship Name" Width="130"></GridColumn>
<GridColumn Field="OrderDate" HeaderText="Order Date" Width="100" Format="d" Type="ColumnType.Date"></GridColumn>
</GridColumns>
</SfGrid>
</div>
</div>
</div>
@code {
private DateTime CurrentDate { get; set; } = new DateTime(2026, 3, 24);
private SfSchedule<AppointmentData> ScheduleRef;
private SfGrid<OrderData> GridRef;
private List<AppointmentData> ScheduleData { get; set; } = new List<AppointmentData>
{
new AppointmentData
{
Id = 1,
Subject = "Meeting",
StartTime = new DateTime(2026, 3, 24, 10, 0, 0),
EndTime = new DateTime(2026, 3, 24, 11, 30, 0),
Location = "Conference Room",
Description = "Monthly Status Update"
},
new AppointmentData
{
Id = 2,
Subject = "Team Lunch",
StartTime = new DateTime(2026, 3, 25, 12, 0, 0),
EndTime = new DateTime(2026, 3, 25, 13, 0, 0),
Location = "Cafeteria",
Description = "Team Building"
}
};
private List<OrderData> GridData { get; set; } = new List<OrderData>
{
new OrderData
{
OrderID = 10248,
CustomerID = "VINET",
ShipName = "Vins et alcools Chevalier",
ShipCity = "Reims",
ShipAddress = "59 rue de l Abbaye",
ShipPostalCode = "51100",
ShipCountry = "France",
OrderDate = new DateTime(2026, 3, 1)
},
new OrderData
{
OrderID = 10249,
CustomerID = "TOMSP",
ShipName = "Toms Spezialitäten",
ShipCity = "Münster",
ShipAddress = "Luisenstr. 48",
ShipPostalCode = "44087",
ShipCountry = "Germany",
OrderDate = new DateTime(2026, 3, 2)
},
new OrderData
{
OrderID = 10250,
CustomerID = "HANAR",
ShipName = "Hanari Carnes",
ShipCity = "Rio de Janeiro",
ShipAddress = "Rua do Paço, 67",
ShipPostalCode = "05454-876",
ShipCountry = "Brazil",
OrderDate = new DateTime(2026, 3, 3)
}
};
public async Task OnBeforePaste(PasteEventArgs<AppointmentData> args)
{
// Intercept clipboard text and parse grid data
if (args.ClipboardText is string stringData)
{
string[] dataArray = stringData.Split('\t');
if (dataArray.Length >= 5)
{
int id;
if (int.TryParse(dataArray[0], out id))
{
DateTime orderDate;
DateTime.TryParse(dataArray[4], out orderDate);
// Transform grid data to appointment
args.Data = new List<AppointmentData> {
new AppointmentData {
Id = id,
Subject = $"{dataArray[1]}",
StartTime = orderDate,
EndTime = orderDate.AddHours(1),
Location = dataArray[2],
Description = $"Order from {dataArray[3]}"
}
};
}
}
}
}
public class AppointmentData
{
public int Id { get; set; }
public string Subject { get; set; }
public string Location { get; set; }
public DateTime StartTime { get; set; }
public DateTime EndTime { get; set; }
public string Description { get; set; }
public bool IsAllDay { get; set; }
public string RecurrenceRule { get; set; }
public string RecurrenceException { get; set; }
public int? RecurrenceID { get; set; }
}
public class OrderData
{
public int OrderID { get; set; }
public string CustomerID { get; set; }
public string ShipName { get; set; }
public string ShipCity { get; set; }
public string ShipAddress { get; set; }
public string ShipPostalCode { get; set; }
public string ShipCountry { get; set; }
public DateTime OrderDate { get; set; }
}
}Grid to Scheduler Clipboard Integration
The example above demonstrates how to copy data from a Syncfusion Grid and paste it as appointments in the Scheduler:
Steps: 1. Select a row in the grid (Grid data becomes clipboard text via copy operation) 2. Press Ctrl+C to copy the grid row 3. Click on a time slot in the scheduler 4. Press Ctrl+V to paste as a new appointment 5. The Paste event transforms grid data into appointment format
The Paste event receives the clipboard text and the OnBeforePaste handler converts tab-separated grid data into appointment objects with appropriate date/time assignments.
Common Patterns
When to use keyboard shortcuts:
- Quick copy-paste operations by end users
- Duplicating nearby appointments
- Simple appointment management
When to use programmatic methods:
- Context menu integration with custom UI
- Advanced validation before paste
- Transforming data from external sources
- Batch clipboard operations
Data transformation in Paste event:
- Convert grid/table data to appointments
- Adjust dates/times based on target slot
- Add metadata or location information
- Validate before pasting
Mac vs Windows:
- Use Cmd instead of Ctrl for Mac users
- JavaScript interop can detect platform and adapt
Localization
Table of Contents
Setting date format
Display dates in specific format:
@using Syncfusion.Blazor.Schedule
<SfSchedule TValue="AppointmentData" Height="650px" DateFormat="yyyy/MM/dd">
<ScheduleViews>
<ScheduleView Option="View.Day"></ScheduleView>
<ScheduleView Option="View.Week"></ScheduleView>
<ScheduleView Option="View.WorkWeek"></ScheduleView>
<ScheduleView Option="View.Month"></ScheduleView>
<ScheduleView Option="View.Agenda"></ScheduleView>
</ScheduleViews>
</SfSchedule>
@code{
public class AppointmentData
{
public int Id { get; set; }
public string Subject { get; set; }
public string Location { get; set; }
public DateTime StartTime { get; set; }
public DateTime EndTime { get; set; }
public string Description { get; set; }
public bool IsAllDay { get; set; }
public string RecurrenceRule { get; set; }
public string RecurrenceException { get; set; }
public Nullable<int> RecurrenceID { get; set; }
}
}Time mode
Display times in specific format:
@using Syncfusion.Blazor.Schedule
<SfSchedule TValue="AppointmentData" Height="650px" TimeFormat="T">
<ScheduleViews>
<ScheduleView Option="View.Day"></ScheduleView>
<ScheduleView Option="View.Week"></ScheduleView>
<ScheduleView Option="View.WorkWeek"></ScheduleView>
<ScheduleView Option="View.Month"></ScheduleView>
<ScheduleView Option="View.Agenda"></ScheduleView>
</ScheduleViews>
</SfSchedule>
@code{
public class AppointmentData
{
public int Id { get; set; }
public string Subject { get; set; }
public string Location { get; set; }
public DateTime StartTime { get; set; }
public DateTime EndTime { get; set; }
public string Description { get; set; }
public bool IsAllDay { get; set; }
public string RecurrenceRule { get; set; }
public string RecurrenceException { get; set; }
public Nullable<int> RecurrenceID { get; set; }
}
}RTL Support
Enable right-to-left layout:
@using Syncfusion.Blazor.Schedule
<SfSchedule TValue="AppointmentData" Height="550px" EnableRtl="true" @bind-SelectedDate="@CurrentDate">
<ScheduleEventSettings DataSource="@DataSource"></ScheduleEventSettings>
<ScheduleViews>
<ScheduleView Option="View.Week"></ScheduleView>
</ScheduleViews>
</SfSchedule>
@code{
DateTime CurrentDate = new DateTime(2026, 3, 24);
List<AppointmentData> DataSource = new List<AppointmentData>();
public class AppointmentData
{
public int Id { get; set; }
public string Subject { get; set; }
public DateTime StartTime { get; set; }
public DateTime EndTime { get; set; }
}
}