Skip to main content
All docs
V24.1

Bind Blazor Scheduler to Data

  • 7 minutes to read

The DevExpress Blazor Scheduler works with the DxSchedulerDataStorage object that contains source data for the following Scheduler persistent objects:

DxSchedulerDataStorage maps data source fields to persistent object properties. This class also includes API that allows you to retrieve and manage persistent objects.

Scheduler and Data Storage - Scheme

Common Steps

Follow the steps below to bind a Scheduler component to data:

  1. Create a DxSchedulerDataStorage object. Use the constructor without parameters.
  2. Use the DxSchedulerDataStorage.AppointmentsSource property to populate the storage with a collection of data objects.
  3. Create a DxSchedulerAppointmentMappings object and map data source fields to appointment properties.
  4. Assign the created DxSchedulerAppointmentMappings object to the DxSchedulerDataStorage.AppointmentMappings property.
  5. Assign the data source to the Scheduler’s DataStorage property.

Bind to Runtime Data

You can bind the DevExpress Scheduler to data created at runtime. In this case, newly created appointments do not persist when you close the application. If you need to save changes, bind the Scheduler to a remote data source instead.

<DxScheduler StartDate="@DateTime.Today" 
             DataStorage="@DataStorage">
    <DxSchedulerWeekView ShowWorkTimeOnly="true"></DxSchedulerWeekView>
</DxScheduler>

@code {
    DxSchedulerDataStorage DataStorage = new DxSchedulerDataStorage() {
        AppointmentsSource = AppointmentCollection.GetAppointments(),
        AppointmentMappings = new DxSchedulerAppointmentMappings() {
            Type = "AppointmentType",
            Start = "StartDate",
            End = "EndDate",
            Subject = "Caption",
            AllDay = "AllDay",
            Location = "Location",
            Description = "Description",
            LabelId = "Label",
            StatusId = "Status",
            RecurrenceInfo = "Recurrence"
        }
    };
}

Scheduler Appointment Mappings

Read Tutorial: Get Started with Scheduler

Watch Video: Get Started with Scheduler

Run Demo: Scheduler - Recurring Appointments

Bind to Remote Data

Bind to Data with Entity Framework Core

You can use Entity Framework Core in Blazor Server applications. Follow the steps below to bind the DevExpress Scheduler to data.

  1. Fetch data from a database. See steps 1-6 in the following article:

    Read Tutorial: Bind Components to Data with Entity Framework Core

  2. Add a Scheduler to your application and bind it to data (refer to common steps).

  3. Handle Scheduler events to implement CRUD operations. Refer to the following topic for the list of available Scheduler events: Managing Appointments in Code.

The following code snippet does the following:

@inject IDbContextFactory<MedicsSchedulingContext> MedicsSchedulingContextFactory
@implements IDisposable

<DxScheduler StartDate="@startDate"
             DataStorage="@DataStorage"
             AppointmentUpdated="@AppointmentUpdated"
             AppointmentInserted="@AppointmentInserted"
             AppointmentRemoved="@AppointmentRemoved"
             GroupType="SchedulerGroupType.Resource">
    <DxSchedulerDayView DayCount="1" ShowWorkTimeOnly="true"></DxSchedulerDayView>
    ...
        <Scales>
            <DxSchedulerTimeScale Unit="@SchedulerTimeScaleUnit.Day" UnitCount="1"></DxSchedulerTimeScale>
            <DxSchedulerTimeScale Unit="@SchedulerTimeScaleUnit.Hour" UnitCount="2"></DxSchedulerTimeScale>
        </Scales>
    </DxSchedulerTimelineView>
</DxScheduler>

@code {
    DateTime startDate { get; set; } = new DateTime(2016, 10, 10);
    MedicsSchedulingContext dbContext { get; set; }

    DxSchedulerDataStorage DataStorage = new DxSchedulerDataStorage() {
            AppointmentsSource = null,
            AppointmentMappings = new DxSchedulerAppointmentMappings() {
                Id = "Id",
                Type = "EventType",
                Start = "StartTime",
                End = "EndTime",
                Subject = "Subject",
                AllDay = "AllDay",
                Location = "Location",
                Description = "Description",
                LabelId = "Label",
                StatusId = "Status",
                ResourceId = "MedicId",
                RecurrenceInfo = "RecurrenceInfo"
            },
            ResourcesSource = null,
            ResourceMappings = new DxSchedulerResourceMappings() {
                Id = "Id",
                Caption = "DisplayName"
            }
        };

    protected override void OnInitialized() {
        dbContext = MedicsSchedulingContextFactory.CreateDbContext();
        DataStorage.AppointmentsSource = dbContext.MedicalAppointments.ToList();
        DataStorage.ResourcesSource = dbContext.Medics.ToList();
    }

    void AppointmentInserted(DxSchedulerAppointmentItem e) {
        dbContext.Add(e.SourceObject);
        dbContext.SaveChanges();
    }

    void AppointmentUpdated(DxSchedulerAppointmentItem e) {
        dbContext.SaveChanges();
    }

    void AppointmentRemoved(DxSchedulerAppointmentItem e) {
        dbContext.Remove(e.SourceObject);
        dbContext.SaveChanges();
    }

    public void Dispose() {
        dbContext?.Dispose();
    }
}

Bind to data with EF Core

Bind to a Web API Service

You can use a Web API service to bind the DevExpress Blazor Scheduler to remote data.

View Example: Scheduler for Blazor - How to implement CRUD operations with a Web API Service

The following code snippet does the following:

  • Creates a DxSchedulerDataStorage object, sets its AppointmentsSource to null.
  • Assigns the created data storage object to the Scheduler’s DataStorage property.
  • In the OnInitializedAsync lifecycle method, defines the AppointmentsSource to populate the data storage with medical appointments (a Web API service is used).
  • Handles AppointmentInserting, AppointmentUpdating, and AppointmentRemoving events to implement CRUD operations in the Scheduler. These events fire before modifications are applied to Scheduler’s appointment collection. You can access a database or another service and validate that an appointment was inserted/updated/removed. If validation is successful, pass the appointment further. If not, set the event argument’s Cancel property to true and display an error message (the service is unavailable or the appointment conflicts with another appointment in the database).

    To access a target appointment or modify its properties from event handlers, use the Appointment property.

    You can also use AppointmentInserted, AppointmentUpdated, and AppointmentRemoved events to implement CRUD operations. These events fire after modifications are applied to the Scheduler’s collection. Use these events if you do not need to validate data.

    Refer to the following topic for the complete list of available Scheduler events: Managing Appointments in Code.

@inject HttpClient Http

@using System.Text.Json
@using System.Text.Json.Serialization
@using System.Text

<DxScheduler Id="schedulerWeekView"
             StartDate="@startDate"
             DataStorage="@DataStorage"
             AppointmentInserting="AppointmentInserting"
             AppointmentRemoving="AppointmentRemoving"
             AppointmentUpdating="AppointmentUpdating">
    <DxSchedulerDayView ShowWorkTimeOnly="true"></DxSchedulerDayView>
</DxScheduler>

@code {
    protected DateTime startDate { get; set; } = new DateTime(2016, 10, 10);
    DxSchedulerDataStorage DataStorage = new DxSchedulerDataStorage() {
            AppointmentsSource = null,
            AppointmentMappings = new DxSchedulerAppointmentMappings() {
                Id = "id",
                Type = "eventType",
                Start = "startTime",
                End = "endTime",
                Subject = "subject",
                AllDay = "allDay",
                Location = "location",
                Description = "description",
                LabelId = "label",
                StatusId = "status",
            }
        };

    string fullWebAPIUrl = "https://localhost:44310/api/MedicalAppointments/";

    protected override async Task OnInitializedAsync() {
        var response = await Http.GetAsync(fullWebAPIUrl);

        if (response.IsSuccessStatusCode) {
            using var responseStream = await response.Content.ReadAsStreamAsync();
            DataStorage.AppointmentsSource = await JsonSerializer.DeserializeAsync<IEnumerable<MedicalAppointments>>(responseStream);
        }
    }

    async Task<HttpResponseMessage> PostItemAsync(MedicalAppointments item) {
        var myContent = JsonSerializer.Serialize(item);

        var response = await Http.PostAsync(fullWebAPIUrl, new StringContent(myContent, Encoding.Unicode, "application/json"));
        return response;
    }

    async Task AppointmentInserting(SchedulerAppointmentOperationEventArgs e) {
        MedicalAppointments insertedItem = e.Appointment.SourceObject as MedicalAppointments;
        HttpResponseMessage response = await PostItemAsync(insertedItem);

        if(response.IsSuccessStatusCode) {
            using var responseStream = await response.Content.ReadAsStreamAsync();
            MedicalAppointments newItem = await JsonSerializer.DeserializeAsync<MedicalAppointments>(responseStream);
            insertedItem.id = newItem.id;
        }
        else
            e.Cancel = true;
    }

    async Task AppointmentUpdating(SchedulerAppointmentOperationEventArgs e) {
        MedicalAppointments updatedItem = e.Appointment.SourceObject as MedicalAppointments;

        var myContent = JsonSerializer.Serialize(updatedItem);
        var request = new HttpRequestMessage(HttpMethod.Put, fullWebAPIUrl + Convert.ToInt32(updatedItem.id));
        request.Content = new StringContent(myContent, Encoding.Unicode, "application/json");

        var response = await Http.SendAsync(request);
        if(!response.IsSuccessStatusCode)
            e.Cancel = true;
    }

    async Task AppointmentRemoving(SchedulerAppointmentOperationEventArgs e) {
        var response = await Http.DeleteAsync(fullWebAPIUrl + e.Appointment.Id);
        if (!response.IsSuccessStatusCode)
            e.Cancel = true;
    }
}

Scheduler - Bind to a Web API service