blazor-404771-components-scheduler-bind-to-data.md
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.
Follow the steps below to bind a Scheduler component to data:
DxSchedulerAppointmentMappings object to the DxSchedulerDataStorage.AppointmentMappings property.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"
}
};
}
public class Appointment {
public Appointment() {}
public int AppointmentType { get; set; }
public DateTime StartDate { get; set; }
public DateTime EndDate { get; set; }
public string Caption { get; set; }
public string Description { get; set; }
public string Location { get; set; }
public int Label { get; set; }
public int Status { get; set; }
public bool AllDay { get; set; }
public string Recurrence { get; set; }
}
public static partial class AppointmentCollection {
public static List<Appointment> GetAppointments() {
DateTime date = DateTime.Today;
var dataSource = new List<Appointment>() {
new Appointment {
Caption = "Install New Router in Dev Room",
StartDate = date + (new TimeSpan(0, 10, 0, 0)),
EndDate = date + (new TimeSpan(0, 12, 0, 0)),
Label = 6,
Status = 1
},
new Appointment {
Caption = "Upgrade Personal Computers",
StartDate = date + (new TimeSpan(0, 13, 0, 0)),
EndDate = date + (new TimeSpan(0, 14, 30, 0)),
Label = 1,
Status = 1
},
new Appointment {
Caption = "Website Redesign Plan",
StartDate = date + (new TimeSpan(1, 9, 30, 0)),
EndDate = date + (new TimeSpan(1, 11, 30, 0)),
Label = 1,
Status = 1
},
// ...
};
return dataSource;
}
}
Read Tutorial: Get Started with Scheduler
Run Demo: Scheduler - Recurring Appointments
You can use Entity Framework Core in Blazor Server applications. Follow the steps below to bind the DevExpress Scheduler to data.
Fetch data from a database. See steps 1-6 in the following article:
Add a Scheduler to your application and bind it to data (refer to common steps).
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:
Creates a DxSchedulerDataStorage object, sets its AppointmentsSource to null.
Assigns the created data storage object to the Scheduler’s DataStorage property.
In the OnInitialized lifecycle method, creates a new DbContext and loads data from the DbContext to the DxSchedulerDataStorage.AppointmentsSource property.
Handles AppointmentInserted, AppointmentUpdated, and AppointmentRemoved events to implement CRUD operations in the Scheduler. To access a target appointment, the SourceObject property is used.
Uses the DbContext.Dispose method to track the context for the component lifetime.
@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();
}
}
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:
null.true and display an error message (the service is unavailable or the appointment conflicts with another appointment in the database).@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;
}
}