Skip to main content

Get Started with DevExpress Scheduler for .NET MAUI

  • 4 minutes to read

The DevExpress Mobile UI for .NET MAUI suite contains a set of the following views to display and manage appointments (scheduled events): DayView, WorkWeekView, WeekView, and MonthView.

This tutorial explains how to create a WorkWeekView instance and bind it with a data source that stores appointments.

View Example: Get Started with DevExpress Scheduler for .NET MAUI

>Day View<

Prerequisites

Refer to the following pages before you proceed with this Getting Started lesson:

Create a New Application and Place a Scheduler on the Main Page

  1. Create a new .NET MAUI cross-platform solution (for example, Scheduler_GettingStarted) and install the DevExpress.Maui.Scheduler NuGet Package. See the following topic for more information: Register DevExpress NuGet Gallery to Access Mobile UI for .NET MAUI.

    Tip

    You can also use DevExpress Project Templates to create a new application. See the following topic for more information: CLI Project Templates.

  2. In the MainPage.xaml file, declare the dxsch XAML namespace and add a WorkWeekView to a content page:

    <ContentPage xmlns="http://schemas.microsoft.com/dotnet/2021/maui"
                 xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
                 xmlns:dxsch="clr-namespace:DevExpress.Maui.Scheduler;assembly=DevExpress.Maui.Scheduler"
                 xmlns:local="clr-namespace:Scheduler_GettingStarted"
                 x:Class="Scheduler_GettingStarted.MainPage">
        <dxsch:WorkWeekView/>
    </ContentPage>
    

Prepare a Model and View Model

  1. Add the following classes that represent data objects in the application:

    • MedicalAppointment—an appointment to be displayed in the scheduler.
    • ReceptionDeskData—a data source that stores data for the scheduler. The MedicalAppointments property provides access to the appointments.
    using System.Collections.ObjectModel;
    
    namespace Scheduler_GettingStarted {
        public class MedicalAppointment {
            public int Id { get; set; }
            public DateTime StartTime { get; set; }
            public DateTime EndTime { get; set; }
            public string Subject { get; set; }
            public int LabelId { get; set; }
            public string Location { get; set; }
        }
    
        public class ReceptionDeskData {
            public static DateTime BaseDate = DateTime.Today;
    
            public static string[] PatientNames = { "Andrew Glover", "Mark Oliver", 
                                                    "Taylor Riley", "Addison Davis", 
                                                    "Benjamin Hughes", "Lucas Smith",
                                                    "Robert King", "Laura Callahan", 
                                                    "Miguel Simmons", "Isabella Carter", 
                                                    "Andrew Fuller", "Madeleine Russell",
                                                    "Steven Buchanan", "Nancy Davolio", 
                                                    "Michael Suyama", "Margaret Peacock", 
                                                    "Janet Leverling", "Ariana Alexander",
                                                    "Brad Farkus", "Bart Arnaz", 
                                                    "Arnie Schwartz", "Billy Zimmer"};
    
            static Random rnd = new Random();
    
            void CreateMedicalAppointments() {
                int appointmentId = 1;
                int patientIndex = 0;
                DateTime start;
                TimeSpan duration;
                ObservableCollection<MedicalAppointment> result = 
                                                         new ObservableCollection<MedicalAppointment>();
                for (int i = -20; i < 20; i++)
                    for (int j = 0; j < 15; j++) {
                        int room = rnd.Next(1, 100);
                        start = BaseDate.AddDays(i).AddHours(rnd.Next(8, 17)).AddMinutes(rnd.Next(0, 40));
                        duration = TimeSpan.FromMinutes(rnd.Next(20, 30));
                        result.Add(CreateMedicAppointment(appointmentId, PatientNames[patientIndex],
                                                        start, duration, room));
                        appointmentId++;
                        patientIndex++;
                        if (patientIndex >= PatientNames.Length - 1)
                            patientIndex = 1;
                    }
                MedicalAppointments = result;
            }
    
            MedicalAppointment CreateMedicAppointment(int appointmentId, string patientName,
                                                        DateTime start, TimeSpan duration, int room) {
                MedicalAppointment medicalAppointment = new MedicalAppointment();
                medicalAppointment.Id = appointmentId;
                medicalAppointment.StartTime = start;
                medicalAppointment.EndTime = start.Add(duration);
                medicalAppointment.Subject = patientName;
    
                // Assign one of the predefined labels to an appointment
                medicalAppointment.LabelId = rnd.Next(1, 10); 
    
                medicalAppointment.Location = String.Format("{0}", room);
                return medicalAppointment;
            }
    
            public ObservableCollection<MedicalAppointment> MedicalAppointments { get; private set; }
    
            public ReceptionDeskData() {
                CreateMedicalAppointments();
            }
        }
    }
    
  2. Declare the ReceptionDeskViewModel class that contains appointments for the scheduler.

    using System.ComponentModel;
    
    namespace Scheduler_GettingStarted {
        public class ReceptionDeskViewModel : INotifyPropertyChanged {
            readonly ReceptionDeskData data;
    
            public event PropertyChangedEventHandler PropertyChanged;
            public DateTime StartDate { get { return ReceptionDeskData.BaseDate; } }
            public IReadOnlyList<MedicalAppointment> MedicalAppointments 
                                { get => data.MedicalAppointments; }
    
            public ReceptionDeskViewModel() {
                data = new ReceptionDeskData();
            }
    
            protected void RaisePropertyChanged(string name) {
                if (PropertyChanged != null)
                    PropertyChanged(this, new PropertyChangedEventArgs(name));
            }
        }
    }
    

Bind the Scheduler to the View Model

In the MainPage.xaml file:

  1. Assign a ReceptionDeskViewModel object to the content page’s BindingContext property.
  2. Set the WorkWeekView.DataStorage property to a SchedulerDataStorage object and use the SchedulerDataStorage.DataSource property to bind the scheduler to a source of appointments.
  3. Set the DataSource.AppointmentsSource property to the collection of appointment objects.
  4. Use the DataSource.AppointmentMappings property to map appointment properties to the MedicalAppointment class properties.
<ContentPage xmlns="http://schemas.microsoft.com/dotnet/2021/maui"
             xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
             xmlns:local="clr-namespace:Scheduler_GettingStarted"
             xmlns:dxsch="clr-namespace:DevExpress.Maui.Scheduler;assembly=DevExpress.Maui.Scheduler"
             x:Class="Scheduler_GettingStarted.MainPage">
    <ContentPage.BindingContext>
        <local:ReceptionDeskViewModel/>
    </ContentPage.BindingContext>
    <dxsch:WorkWeekView>
        <dxsch:WorkWeekView.DataStorage>
            <dxsch:SchedulerDataStorage>
                <dxsch:SchedulerDataStorage.DataSource>
                    <dxsch:DataSource AppointmentsSource="{Binding MedicalAppointments}">
                        <dxsch:DataSource.AppointmentMappings>
                            <dxsch:AppointmentMappings 
                            Id="Id" 
                            Start="StartTime" 
                            End="EndTime" 
                            Subject="Subject"
                            LabelId="LabelId"
                            Location="Location"/>
                        </dxsch:DataSource.AppointmentMappings>
                    </dxsch:DataSource>
                </dxsch:SchedulerDataStorage.DataSource>
            </dxsch:SchedulerDataStorage>
        </dxsch:WorkWeekView.DataStorage>
    </dxsch:WorkWeekView>
</ContentPage>