The .NET MAUI Scheduler control has nine types of built-in configurable view modes that provide basic functionalities for scheduling, managing, and representing appointments efficiently. It allows you to schedule events from any database. You can also easily bind any custom event (business) objects to populate appointments or events.
For that, the name of the custom event class and the properties are arbitrary. The property type should follow the same API-type pattern as in the SchedulerAppointment, with basic details such as start and end times, subjects, locations, and so on.
Let’s walk through the steps to create custom event objects and bind the object properties in .NET MAUI Scheduler.
Note: If you are new to our .NET MAUI Scheduler control, then please read Getting Started with .NET MAUI Scheduler before proceeding.
First, initialize the .NET MAUI Scheduler to add it to your application.
<ContentPage . . . xmlns:scheduler="clr-namespace:Syncfusion.Maui.Scheduler;assembly=Syncfusion.Maui.Scheduler"> <scheduler:SfScheduler /> </ContentPage>
Then, create a custom class with the basic details such as start and end times, subjects, location, and so on. The custom class should contain the DateTime field with the start and end times of the event.
Refer to the following code example. Here, we are going to create the custom class Event with the mandatory fields From, To, EventName, and so on.
/// <summary> /// Represents the custom data properties. /// </summary> public class Event : INotifyPropertyChanged { private DateTime from, to; private string eventName; private bool isAllDay; private TimeZoneInfo startTimeZone, endTimeZone; private Brush background; private string notes; /// <summary> /// Property changed event handler. /// </summary> public event PropertyChangedEventHandler PropertyChanged; /// <summary> /// Gets or sets the value to display the start date. /// </summary> public DateTime From { get { return from; } set { from = value; this.RaiseOnPropertyChanged(nameof(From)); } } /// <summary> /// Gets or sets the value to display the end date. /// </summary> public DateTime To { get { return to; } set { to = value; this.RaiseOnPropertyChanged(nameof(To)); } } /// <summary> /// Gets or sets the value indicating whether the appointment is all-day or not. /// </summary> public bool IsAllDay { get { return isAllDay; } set { isAllDay = value; this.RaiseOnPropertyChanged(nameof(IsAllDay)); } } /// <summary> /// Gets or sets the value to display the subject. /// </summary> public string EventName { get { return eventName; } set { eventName = value; this.RaiseOnPropertyChanged(nameof(EventName)); } } /// <summary> /// Gets or sets the value to display the notes. /// </summary> public string Notes { get { return notes; } set { notes = value; this.RaiseOnPropertyChanged(nameof(Notes)); } } /// <summary> /// Gets or sets the value to display the start time zone. /// </summary> public TimeZoneInfo StartTimeZone { get { return startTimeZone; } set { startTimeZone = value; this.RaiseOnPropertyChanged(nameof(StartTimeZone)); } } /// <summary> /// Gets or sets the value to display the end time zone. /// </summary> public TimeZoneInfo EndTimeZone { get { return endTimeZone; } set { endTimeZone = value; this.RaiseOnPropertyChanged(nameof(EndTimeZone)); } } /// <summary> /// Gets or sets the value to display the background. /// </summary> public Brush Background { get { return background; } set { background = value; this.RaiseOnPropertyChanged(nameof(Background)); } } /// <summary> /// Invoke method when property changed. /// </summary> /// <param name="propertyName">property name</param> private void RaiseOnPropertyChanged(string propertyName) { this.PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName)); } }
Note: Inherit the Event class from the INotifyPropertyChanged to dynamically update the custom data.
Now, map the custom event object properties by configuring the AppointmentMapping property. This property is used to create the SchedulerAppointment internally.
Refer to the following table to map the custom event properties using the AppointmentMapping properties.
Property Name | Description |
StartTime | Maps the custom appointment From property to the Scheduler appointment StartTime property. |
EndTime
| Maps the custom appointment To property to the Scheduler appointment EndTime property. |
StartTimeZone | Maps the custom appointment StartTimeZone property to the Scheduler appointment StartTimeZone property. |
EndTimeZone
| Maps the custom appointment EndTimeZone property to the Scheduler appointment EndTimeZone property. |
Subject
| Maps the custom appointment Subject property to the Scheduler appointment Subject property. |
Id
| Binds the custom appointment Id property to the data source field. |
Background
| Maps the custom appointment Background property to the Scheduler appointment Background property. |
IsAllDay
| Maps the custom appointment IsAllDay property to the Scheduler appointment IsAllDay property. |
RecurrenceRule
| Maps the custom appointment RecurrenceRule property to the Scheduler appointment RecurrenceRule property. |
RecurrenceId
| Maps the custom appointment RecurrenceId property to the Scheduler appointment RecurrenceId property. |
Notes
| Maps the custom appointment Notes property to the Scheduler appointment Notes property. |
Location
| Maps the custom appointment Location property to the Scheduler appointment Location property. |
RecurrenceExceptionDates
| Maps the custom appointment RecurrenceExceptions property to the Scheduler appointment RecurrenceExceptionDates property. |
IsReadOnly | Binds the custom appointment IsReadOnly property to the data source field. |
Refer to the following code example.
<scheduler:SfScheduler x:Name="Scheduler" View="Week" > <scheduler:SfScheduler.AppointmentMapping> <scheduler:SchedulerAppointmentMapping Subject="EventName" StartTime="From" EndTime="To" Background="Background" IsAllDay="IsAllDay" StartTimeZone="StartTimeZone" EndTimeZone="EndTimeZone" Id="Id" RecurrenceExceptionDates="RecurrenceExceptions" RecurrenceRule="RecurrenceRule" RecurrenceId="RecurrenceId"/> </scheduler:SfScheduler.AppointmentMapping> </scheduler:SfScheduler>
Let’s create and assign the collection of custom event objects to the AppointmentsSource property to create the Scheduler appointments or events.
Refer to the following code examples.
Here, we are going to create the custom event objects collection of type ObservableCollection<Event> with the required appointment details.
/// <summary> /// The business object view model. /// </summary> public class BusinessObjectViewModel { #region Fields /// <summary> /// team management /// </summary> private List<string> subjectCollection; /// <summary> /// Notes Collection. /// </summary> private List<string> noteCollection; /// <summary> /// color collection /// </summary> private List<Brush> colorCollection; #endregion #region Constructor /// <summary> /// Initializes a new instance of the <see cref="BusinessObjectViewModel" /> class. /// </summary> public BusinessObjectViewModel() { this.CreateSubjectCollection(); this.CreateColorCollection(); this.CreateNoteCollection(); this.IntializeAppoitments(); this.DisplayDate = DateTime.Now.Date.AddHours(8).AddMinutes(50); } #endregion Constructor #region Properties /// <summary> /// Gets or sets the schedule display date. /// </summary> public DateTime DisplayDate { get; set; } /// <summary> /// Gets or sets appointments. /// </summary> public ObservableCollection<Event> Events { get; set; } #endregion #region Methods /// <summary> /// Method to create the note collection. /// </summary> private void CreateNoteCollection() { this.noteCollection = new List<string>(); this.noteCollection.Add("Consulting firm laws with business advisers"); this.noteCollection.Add("Execute Project Scope"); this.noteCollection.Add("Project Scope & Deliverables"); this.noteCollection.Add("Executive summary"); this.noteCollection.Add("Try to reduce the risks"); this.noteCollection.Add("Encourages the integration of mind, body, and spirit"); this.noteCollection.Add("Execute Project Scope"); this.noteCollection.Add("Project Scope & Deliverables"); this.noteCollection.Add("Executive summary"); this.noteCollection.Add("Try to reduce the risk"); } /// <summary> /// Method to initialize the appointments. /// </summary> private void IntializeAppoitments() { this.Events = new ObservableCollection<Event>(); Random randomTime = new Random(); List<Point> randomTimeCollection = this.GettingTimeRanges(); DateTime date; DateTime dateFrom = DateTime.Now.AddDays(-50); DateTime dateTo = DateTime.Now.AddDays(50); for (date = dateFrom; date < dateTo; date = date.AddDays(1)) { if (date.Day % 7 != 0) { for (int additionalAppointmentIndex = 0; additionalAppointmentIndex < 1; additionalAppointmentIndex++) { var meeting = new Event(); int hour = randomTime.Next((int)randomTimeCollection[additionalAppointmentIndex].X, (int)randomTimeCollection[additionalAppointmentIndex].Y); meeting.From = new DateTime(date.Year, date.Month, date.Day, hour, 0, 0); meeting.To = meeting.From.AddHours(1); meeting.EventName = this.subjectCollection[randomTime.Next(9)]; meeting.Background = this.colorCollection[randomTime.Next(10)]; meeting.IsAllDay = false; meeting.Notes = this.noteCollection[randomTime.Next(10)]; meeting.StartTimeZone = TimeZoneInfo.Local; meeting.EndTimeZone = TimeZoneInfo.Local; this.Events.Add(meeting); } } else { var meeting = new Event(); meeting.From = new DateTime(date.Year, date.Month, date.Day, randomTime.Next(9, 11), 0, 0); meeting.To = meeting.From.AddDays(2).AddHours(1); meeting.EventName = this.subjectCollection[randomTime.Next(10)]; meeting.Background = this.colorCollection[randomTime.Next(10)]; meeting.IsAllDay = true; meeting.Notes = this.noteCollection[randomTime.Next(9)]; meeting.StartTimeZone = TimeZoneInfo.Local; meeting.EndTimeZone = TimeZoneInfo.Local; this.Events.Add(meeting); } } } /// <summary> /// Method to create the subject collection. /// </summary> private void CreateSubjectCollection() { this.subjectCollection = new List<string>(); this.subjectCollection.Add("General Meeting"); this.subjectCollection.Add("Plan Execution"); this.subjectCollection.Add("Project Plan"); this.subjectCollection.Add("Consulting"); this.subjectCollection.Add("Performance Check"); this.subjectCollection.Add("Support"); this.subjectCollection.Add("Development Meeting"); this.subjectCollection.Add("Scrum"); this.subjectCollection.Add("Project Completion"); this.subjectCollection.Add("Release updates"); this.subjectCollection.Add("Performance Check"); } /// <summary> /// Method for get timing range. /// </summary> /// <returns>return time collection</returns> private List<Point> GettingTimeRanges() { List<Point> randomTimeCollection = new List<Point>(); randomTimeCollection.Add(new Point(9, 11)); randomTimeCollection.Add(new Point(12, 14)); randomTimeCollection.Add(new Point(15, 17)); return randomTimeCollection; } /// <summary> /// Method to create the color collection. /// </summary> private void CreateColorCollection() { this.colorCollection = new List<Brush>(); this.colorCollection.Add(new SolidColorBrush(Color.FromArgb("#FF8B1FA9"))); this.colorCollection.Add(new SolidColorBrush(Color.FromArgb("#FFD20100"))); this.colorCollection.Add(new SolidColorBrush(Color.FromArgb("#FFFC571D"))); this.colorCollection.Add(new SolidColorBrush(Color.FromArgb("#FF36B37B"))); this.colorCollection.Add(new SolidColorBrush(Color.FromArgb("#FF3D4FB5"))); this.colorCollection.Add(new SolidColorBrush(Color.FromArgb("#FFE47C73"))); this.colorCollection.Add(new SolidColorBrush(Color.FromArgb("#FF636363"))); this.colorCollection.Add(new SolidColorBrush(Color.FromArgb("#FF85461E"))); this.colorCollection.Add(new SolidColorBrush(Color.FromArgb("#FF0F8644"))); this.colorCollection.Add(new SolidColorBrush(Color.FromArgb("#FF01A1EF"))); } #endregion }
Then, bind the custom event objects collection to the AppointmentsSource property of the SfScheduler.
<scheduler:SfScheduler x:Name="Scheduler" AppointmentsSource="{Binding Events}" DisplayDate="{Binding DisplayDate}" View="Week" AllowedViews="Day,Week,WorkWeek,Month,TimelineDay,TimelineWeek,TimelineWorkWeek,TimelineMonth"> <scheduler:SfScheduler.AppointmentMapping> <scheduler:SchedulerAppointmentMapping Subject="EventName" StartTime="From" EndTime="To" Background="Background" IsAllDay="IsAllDay" StartTimeZone="StartTimeZone" EndTimeZone="EndTimeZone" /> </scheduler:SfScheduler.AppointmentMapping> <scheduler:SfScheduler.BindingContext> <local:BusinessObjectViewModel/> </scheduler:SfScheduler.BindingContext> </scheduler:SfScheduler>
Also, check out the complete example for creating and binding custom event objects in .NET MAUI Scheduler.
Thanks for reading! In this blog, we have seen how to create and bind custom event (business) objects using the Syncfusion .NET MAUI Scheduler. Along with this, .NET MAUI Scheduler offers loading data on demand, agenda views, block-out dates, appearance customization, and more. Check out the .NET MAUI Scheduler documentation for more details.
If you have any feedback, special requirements, or controls that you’d like to see in our .NET MAUI suite, please let us know in the comments section.
Also, you can contact us through our support forum, support portal, or feedback portal. We are always happy to assist you!