Lesson 1 - Bind a Scheduler to Data Using WCF RIA Services
- 8 minutes to read
This document demonstrates how to create a simple scheduling application with the SchedulerControl, and how to provide appointment data for it. The SchedulerControl can be populated with data through different sources. In this tutorial, we will bind SchedulerControl to a local SQL Server 2008 R2 Express database using WCF RIA Services. To do this, we will first create entities (entity data model) that will represent database tables and then create a domain service that will make these entities available to a Silverlight client to represent data via SchedulerControl.
This topic also describes how to map all required data fields for scheduler appointments, and how to commit changes to a database when data is modified in the SchedulerControl.
NOTE
This example requires the availability of a local SQL Server 2008 R2 Express instance (“.\SQLEXPRESS”).
Therefore, do the following to create a scheduling RIA Services application.
- Step 1. Create a New Solution and Add a Scheduler Control
- Step 2. Create an Entity Data Model
- Step 3. Create a Domain Service
- Step 4. Bind the Scheduler to Data
- Step 5. Specify Mappings
- Step 6. Customize the Scheduler
- Step 7. Commit Changes to the Database
- Result
#Step 1. Create a New Solution and Add a Scheduler Control
Create a new Silverlight Application and check Enable WCF RIA Services.
A newly created solution consists of two projects:
- SilverlightApplication1 - a client project that contains Silverlight code;
- SilverlightApplication1.Web - a server project that contains ASP.NET web application code.
Open the MainPage.xaml file (the SilverlightAplication1 project) in the Designer and add the SchedulerControl object to the project. You can do this by dragging SchedulerControl item from the DX.14.2.Silverlight: Scheduling toolbox tab.
Set the SchedulerControl.HorizontalAlignment and SchedulerControl.VerticalAlignment properties to Stretch. This will stretch the scheduler control to fill the whole page.
After this, your XAML may look like following.
<UserControl x:Class="SilverlightApplication1.MainPage" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:d="http://schemas.microsoft.com/expression/blend/2008" xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" xmlns:dxsch="http://schemas.devexpress.com/winfx/2008/xaml/scheduler" mc:Ignorable="d" d:DesignHeight="478" d:DesignWidth="590" > <Grid x:Name="LayoutRoot" Background="White"> <dxsch:SchedulerControl Name="schedulerControl1" HorizontalAlignment="Stretch" VerticalAlignment="Stretch"> </dxsch:SchedulerControl> </Grid> </UserControl>
Note that you can add SchedulerControl by overwriting your MainPage.xaml file with this code without dragging the SchedulerControl control to the page. However, in this instance, you need to manually add references to the following libraries: DevExpress.Data.v14.2, DevExpress.Xpf.Core.v14.2, DevExpress.Xpf.Scheduler.v14.2, DevExpress.XtraScheduler.v14.2.Core.
NOTE
You can find assembly files at the following location: C:\Program Files (x86)\DevExpress 14.
2\Components\Bin\Silverlight
Since the most common way of using a scheduler is to bind it to a datasource, proceed to the next steps to learn how to do this.
#Step 2. Create an Entity Data Model
In this tutorial, we will bind the scheduler to the CarScheduling table of the CarsDB local SQL Server Express database (the CarsDB.mdf file is placed in C:\Users\Public\Documents\DevExpress Demos 14.2\Components\Silverlight\CS\SchedulerDemo.Web\App_Data by default). The scheduler will represent this table as appointments. So, you need to create the ADO.NET Entity class that represents the CarScheduling table of the database.
Right-click the SilverlightApplication1.Web project in the Solution Explorer and add a new item.
Select ADO.NET Entity Data Model and set its name to CarsDBModel.
Click Add. The Entity Data Model Wizard will appear.
Select Generate from database and click Next.
Specify data connection to the CarsDB.mdf database (copy the local database file to your project previously). Then select the CarScheduling table, confirm that Include foreign key columns in the model is checked and finish.
Visual Studio automatically shows a diagram representing the entity data model that you have just created (the CarsDBModel.edmx branch in the Solution Explorer).
- Rebuild the solution.
#Step 3. Create a Domain Service
The next required step is to create a domain service that will expose data entities and operations in the server project to the client project.
- Right-click the SilverlightApplication1.Web project in the Solution Explorer, click Add and New Item.
- Click the Web category and select the Domain Service Class.
Name the class SchedulingDomainService and click Add.
In the appeared Add New Domain Service Class dialog, select the CarScheduling entity and check the Enable Editing check box. Make sure that the Enable client access check box is checked.
Click OK and rebuild the solution.
The SchedulingDomainService class, derived from LinqToEntitiesDomainService<CarsDBEntities>, is generated in a new SchedulingDomainService.cs file of the server project (SilverlightApplication1.Web).
Open this file and examine the SchedulingDomainService class. It has the following characteristics.
- The SchedulingDomainService class is marked with the [EnableClientAccess()] attribute to indicate that this class is available to clients.
- The GetCarScheduling query method that returns an instance of the CarScheduling entity is generated.
- Methods to insert, update, and delete appointments from the records are generated.
After you have build the solution, the SilverlightApplication1.Web.g.cs file with the automatically generated code is created by RIA Services in the Generated_Code folder of the client project (SilverlightApplication1). To view the generated code, select Show All Files from the Project menu or click Show All Files
on the Solution Explorer toolbar.
Open the SilverlightApplication1.Web.g.cs file to examine the generated code. It has the following characteristics.
- The generated code includes the SchedulingDomainContext class derived from System.ServiceModel.DomainServices.Client.DomainContext. This class is a client-side representation of the SchedulingDomainService class. It contains the GetCarSchedulingQuery method that corresponds to the query method created in the domain service.
- The CarScheduling class, derived from System.ServiceModel.DomainServices.Client.Entity, is generated. This class in the client project matches the CarScheduling entity in the server project.
#Step 4. Bind the Scheduler to Data
To automatically retrieve data from a domain context and display this data in a SchedulerControl, use the DomainDataSource non-visual control.
- Add a reference to the System.Windows.Controls.DomainServices assembly in the SilverlightAplication1 project.
Overwrite the content of the MainPage.xaml file (the SilverlightAplication1 project) with the following XAML markup.
<UserControl x:Class="SilverlightApplication1.MainPage" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:d="http://schemas.microsoft.com/expression/blend/2008" xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" xmlns:dxsch="http://schemas.devexpress.com/winfx/2008/xaml/scheduler" xmlns:riaControls="clr-namespace:System.Windows.Controls;assembly=System.Windows.Controls.DomainServices" xmlns:local="clr-namespace:SilverlightApplication1.Web" mc:Ignorable="d" d:DesignHeight="478" d:DesignWidth="590"> <UserControl.Resources> <riaControls:DomainDataSource Name="domainDataSource1" x:Key="appointmentsDomainDataSource" AutoLoad="True" LoadedData="DomainDataSource_LoadedData" QueryName="GetCarSchedulingQuery"> <riaControls:DomainDataSource.DomainContext> <local:SchedulingDomainContext/> </riaControls:DomainDataSource.DomainContext> </riaControls:DomainDataSource> </UserControl.Resources> <Grid x:Name="LayoutRoot" Background="White"> <dxsch:SchedulerControl Name="schedulerControl1" HorizontalAlignment="Stretch" VerticalAlignment="Stretch"> </dxsch:SchedulerControl> </Grid> </UserControl>
Using the code above, specify a domain context (SchedulingDomainContext) for the DomainDataSource control and set the name of the query method (GetCarSchedulingQuery) to be used for loading data (note that the query method name can be with or without the "Query" suffix).
Handle the DomainDataSource.LoadedData event to give an error message if data loading has failed.
To bind the SchedulerControl control to appointment data, provide the entities loaded from the domain context to AppointmentStorage accessed via the SchedulerStorage.AppointmentStorage property.
<dxsch:SchedulerControl Name="schedulerControl1" HorizontalAlignment="Stretch" VerticalAlignment="Stretch"> <dxsch:SchedulerControl.Storage> <dxsch:SchedulerStorage> <dxsch:SchedulerStorage.AppointmentStorage> <dxsch:AppointmentStorage DataSource="{Binding Source={StaticResource ResourceKey=appointmentsDomainDataSource}, Path=Data}"/> </dxsch:SchedulerStorage.AppointmentStorage> </dxsch:SchedulerStorage> </dxsch:SchedulerControl.Storage> </dxsch:SchedulerControl>
#Step 5. Specify Mappings
Now you need to specify standard mappings for appointment properties. To do this, overwrite the content of the MainPage.xaml file of the SilverlightAplication1 project with the following XAML markup.
<UserControl x:Class="SilverlightApplication1.MainPage"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:dxsch="http://schemas.devexpress.com/winfx/2008/xaml/scheduler"
xmlns:riaControls="clr-namespace:System.Windows.Controls;assembly=System.Windows.Controls.DomainServices"
xmlns:local="clr-namespace:SilverlightApplication1.Web"
mc:Ignorable="d"
d:DesignHeight="478" d:DesignWidth="590">
<UserControl.Resources>
<riaControls:DomainDataSource Name="domainDataSource1" x:Key="appointmentsDomainDataSource"
AutoLoad="True" LoadedData="DomainDataSource_LoadedData"
QueryName="GetCarSchedulingQuery">
<riaControls:DomainDataSource.DomainContext>
<local:SchedulingDomainContext/>
</riaControls:DomainDataSource.DomainContext>
</riaControls:DomainDataSource>
</UserControl.Resources>
<Grid x:Name="LayoutRoot" Background="White">
<dxsch:SchedulerControl Name="schedulerControl1"
HorizontalAlignment="Stretch" VerticalAlignment="Stretch">
<dxsch:SchedulerControl.Storage>
<dxsch:SchedulerStorage>
<dxsch:SchedulerStorage.AppointmentStorage>
<dxsch:AppointmentStorage
DataSource="{Binding Source={StaticResource ResourceKey=appointmentsDomainDataSource}, Path=Data}">
<dxsch:AppointmentStorage.Mappings>
<dxsch:AppointmentMapping
Start="StartTime"
End="EndTime"
AllDay="AllDay"
Description="Description"
Label="Label"
Location="Location"
Subject="Subject"
RecurrenceInfo="RecurrenceInfo"
ReminderInfo="ReminderInfo"
Status="Status"
Type="EventType"/>
</dxsch:AppointmentStorage.Mappings>
</dxsch:AppointmentStorage>
</dxsch:SchedulerStorage.AppointmentStorage>
</dxsch:SchedulerStorage>
</dxsch:SchedulerControl.Storage>
</dxsch:SchedulerControl>
</Grid>
</UserControl>
#Step 6. Customize the Scheduler
Change the Start Date
The SchedulerControl object allows you to set the start date on which the scheduler will initially show its data after the project is run. To do this, use the SchedulerControl.Start property, as follows.
Changing the Active View
Initially, the SchedulerControl displays its data using the Day View. But in this instance, we need to manipulate a lot of appointments over several months. The most appropriate view here is either the Week View or Month View. So, set the SchedulerControl.ActiveViewType property value to Week in XAML.
<dxsch:SchedulerControl Name="schedulerControl1" HorizontalAlignment="Stretch" VerticalAlignment="Stretch" ActiveViewType="Week"/>
#Step 7. Commit Changes to the Database
At this stage, you can run the project and start editing data, but changes will not be saved in the database. To complete this example, write the code that posts data modifications to the database. Handle the SchedulerStorage.AppointmentCollectionModified event, and call the DomainDataSource.SubmitChanges method.
<dxsch:SchedulerControl.Storage>
<dxsch:SchedulerStorage
AppointmentCollectionModified="SchedulerStorage_AppointmentCollectionModified">
<!-- ... -->
</dxsch:SchedulerStorage>
</dxsch:SchedulerControl.Storage>
Handle the DomainDataSource.SubmittedChanges event to give an error message if the submit operation can not be completed.
<riaControls:DomainDataSource Name="domainDataSource1" x:Key="appointmentsDomainDataSource"
AutoLoad="True" LoadedData="DomainDataSource_LoadedData"
QueryName="GetCarSchedulingQuery"
SubmittedChanges="DomainDataSource_SubmittedChanges">
<!-- ... -->
</riaControls:DomainDataSource>
#Result
Run the project. The following picture illustrates the resulting scheduler at runtime.