How to: Bind Scheduler to Data using Entity Framework

  • 5 minutes to read

This example describes how to bind the Scheduler to a data source using the Entity Framework Code First approach.

Create New Scheduling Application

  1. Create a new WPF Application project and open the MainWindow.xaml file in the Visual Studio Designer.
  2. Add the SchedulerControl object to your project. You can do this by dragging the SchedulerControl item from the DX.20.1: Scheduling Toolbox tab to the canvas.

    WPFScheduler_DragDropFromToolbox

  3. Right-click the SchedulerControl object and select Layout | Reset All in the context menu to make the SchedulerControl fill the entire window.

Create Data Structure

Create a new file (for example, Data.cs(vb)) and add the data classes to it.

public class AppointmentEntity {
    public int Id { get; set; }
    public string Subject { get; set; }
    public string Description { get; set; }
    public DateTime Start { get; set; }
    public DateTime End { get; set; }
    public int AppointmentType { get; set; }
    public string RecurrenceInfo { get; set; }
    public int ResourceId { get; set; }
    public int Label { get; set; }
}
public class ResourceEntity {
    public int Id { get; set; }
    public string Description { get; set; }
}

Create a Data Context

NOTE

Before creating a Data Context, make sure that the Entity Framework package is added to your Visual Studio. Refer to the Get Entity Framework article for details on how to install the Entity Framework package.

Define a database context (a DBContext class descendant) that represents a session with the database and allows you to query and save class instances.

public class SchedulingContext : DbContext {
    public DbSet<AppointmentEntity> Appointments { get; set; }
    public DbSet<ResourceEntity> Resources { get; set; }
}

Add the SchedulingContext initializer that seeds the database with sample data when the application starts for the first time.

public class SchedulingContextInitializer : DropCreateDatabaseIfModelChanges<SchedulingContext> {
    protected override void Seed(SchedulingContext context) {
        base.Seed(context);

        context.Resources.Add(DataHelper.Personal());
        context.Resources.Add(DataHelper.Education());
        context.Resources.Add(DataHelper.Work());

        context.Appointments.AddRange(DataHelper.Gym());
        context.Appointments.Add(DataHelper.Dentist());
        context.Appointments.Add(DataHelper.Dinner());
        context.Appointments.Add(DataHelper.Disneyland());
        context.Appointments.Add(DataHelper.RR());
        context.Appointments.Add(DataHelper.DayOff());
        context.Appointments.Add(DataHelper.SecondShift());
        context.Appointments.Add(DataHelper.ConferenceCompanyMeeting());
        context.Appointments.Add(DataHelper.ConferenceCustomerRetentionReview());
        context.Appointments.Add(DataHelper.ConferenceDatabaseAndWebsiteReview());
        context.Appointments.Add(DataHelper.ConferenceWeeklyMeeting());
        context.Appointments.Add(DataHelper.TrainingFrenchLesson());
        context.Appointments.Add(DataHelper.TrainingGermanLesson());
        context.Appointments.Add(DataHelper.TrainingTrainStaffOnNewRemoteControls());

        context.SaveChanges();
    }
}

Register the initializer on the application startup callback.

public partial class App : Application {
    protected override void OnStartup(StartupEventArgs e) {
        Database.SetInitializer<SchedulingContext>(new SchedulingContextInitializer());
        base.OnStartup(e);
    }
}

Create a ViewModel

In the Solution Explorer, right-click to invoke the context menu and select Add | Class…. In the invoked Add New Item window, assign the SchedulingViewModel name to the class.

Add the following code to handle data interaction:

  1. Declare two ObservableCollection type collections (Appts and Calendars) which are used for data binding;
public class SchedulingViewModel : ViewModelBase {        
    SchedulingContext context;
    public ObservableCollection<AppointmentEntity> Appts { get { return context.Appointments.Local; } }
    public ObservableCollection<ResourceEntity> Calendars { get { return context.Resources.Local; } }

}

  1. Declare a command (SaveCommand) that calls the SaveChanges method of a SchedulingContext instance to save updated appointments;
public ICommand SaveCommand {
    get {
        return new DelegateCommand(() => {
            context.SaveChanges();
        });
    }
}

  1. Fill the Apps and Calendars collections with data using the Load method.
public SchedulingViewModel() {
    context = new SchedulingContext();
    context.Appointments.Load();
    context.Resources.Load();
}

Set Mapping and Binding in XAML

  1. Set the DataContext property to the SchedulingViewModel:
<Window.DataContext>
    <local:SchedulingViewModel />
</Window.DataContext>
  1. Use the EventToCommand behaviors to bind the AppointmentAdded, AppointmentEdited, AppointmentRemoved and AppointmentRestored events to the corresponding commands:
<dxmvvm:Interaction.Behaviors>
    <dxmvvm:EventToCommand Command="{Binding SaveCommand}" EventName="AppointmentAdded" />
    <dxmvvm:EventToCommand Command="{Binding SaveCommand}" EventName="AppointmentEdited" />
    <dxmvvm:EventToCommand Command="{Binding SaveCommand}" EventName="AppointmentRemoved" />
    <dxmvvm:EventToCommand Command="{Binding SaveCommand}" EventName="AppointmentRestored" />
</dxmvvm:Interaction.Behaviors>
  1. Set the mappings as shown in the code snippet below:
<dxsch:SchedulerControl.DataSource>
    <dxsch:DataSource AppointmentsSource="{Binding Appts}"
                      ResourcesSource="{Binding Calendars}">
        <dxsch:DataSource.ResourceMappings>
            <dxsch:ResourceMappings Caption="Description"
                                    Id="Id" />
        </dxsch:DataSource.ResourceMappings>
        <dxsch:DataSource.AppointmentMappings>
            <dxsch:AppointmentMappings Description="Description"
                                       End="End"
                                       Id="Id"
                                       LabelId="Label"
                                       RecurrenceInfo="RecurrenceInfo"
                                       ResourceId="ResourceId"
                                       Start="Start"
                                       Subject="Subject"
                                       Type="AppointmentType" />
        </dxsch:DataSource.AppointmentMappings>
    </dxsch:DataSource>
</dxsch:SchedulerControl.DataSource>

Run the Application

The following image demonstrates the result:

scheduler-example-illust