Using XamSchedule Solution with WCF RIA Services

[Infragistics] Mihail Mateev / Sunday, October 31, 2010

WCF RIA Services simplifies the development of n-tier solutions for Rich Internet Applications (RIA), such as Silverlight applications.

XamSchedule components could be used with WCF RIA Services. This article explains a possible approach to use together RIA Services and XamSchedule suite.

If you are no familiar with WCF RIA services you could read the article Using the Infragistics XamGrid with WCF RIA Services

XamSchedule suite offers two data connectors used to bind to your schedule data (resources, calendars and activities): ListScheduleDataConnector  and WcfScheduleDataConnector. WcfScheduleDataConnector is used when you need a data from different sources via WCF service.

WCF RIA Services requires a different approach. It enables linking between client and server projects in a single solution and generating code for the client project from the middle-tier code. In this case you have in the client DomainDataSource, DomainContext and classes, corresponding to your tables in the database. The ListScheduleDataConnector  is more appropriate solution when using WCF RIA Services.

Important moments:

  • Project database to have a corresponding data types to Resource ResourceCalendar and Activity (Appointment, Task, Journal) properties.
    Otherwise you need to implement your own data conversion before field mapping. (It is a general requirement when use XamSchedule with data sources) 
  • Load data via DataContext using DataContext.Load(…) method.
  • Update data source using XamScheduleDataManager events to call DataContext.SubmitChanges()

Demo application will demonstrate a way to create  a multi user scheduling application, that uses a SQL Server 2008 database with WCF RIA Services. Application has the same functionalities like the sample used for the article Implementing XamSchedule Solution in Silverlight Applications Using a WcfListDataConnector

Requirements:

  1. NetAdvantage for Silverlight  Line of Business 2010 Vol.3
  2. NetAdvantage for .NET 2010 Vol.3
  3. NetAdvantage Ultimate 2010 Vol.3

Steps to reproduce a demo application.

  • Download Test2008R2 database and attach it to SQL Server 2008 R2 (Express or higher license)
  • Create a Silverlight application, hosted in an ASP.Net application with RIA Services link
  • Create a Data Model
  • Create a Domain Service
  • Add a DomainDataSource instance in the client.
  • Add a ListScheduleDataConnector in the Silverlight Application.
  • Implement a logic to load a data via DomainContext
  • Add a XamScheduleDataManager.
  • Add UI components from Schedule Suite: XamDayView, XamScheduleView, XamMonthView
  • Implement a logic to update appointments using XamScheduleDataManager events.
  • Implement a multi resource and multi calendar support.
  • Implement a runtime change of the view type
  • Implement a runtime support for calendar display mode.
  • Run the application.

 

Download Test2008R2 database and attach it to SQL Server 2008 R2 (Express or higher license)

Download Test2008R2  database, extract it and attach it to your SQL Server

 

Create a Silverlight Application, hosted in ASP.Net web application

Create a Silverlight Application, hosted in ASP.Net web application with RIA Services link  and named XamScheduleRiaDemoApp3.

 

Create a Data Model

In this section, you need to create the ADO.NET Entity classes that represent data from the Test2008R2 database.

Generated ADO.NET Entity classes in Test2008EntitiesModel:

 

Create a Domain Service

Add a domain service to the middle-tier project. A domain service exposes the data entities and operations in the server project to the client project. You can add business logic to the domain service to manage how the client interacts with the data.

Name your domain service class Test2008DomainService.cs.

 

Add a DomainDataSource instance in the client.

   1: <riaControls:DomainDataSource AutoLoad="True" d:DesignData="{d:DesignInstance my:Resource, CreateList=true}" Height="0" LoadedData="ResourceDomainDataSourceLoadedData" Name="resourceDomainDataSource" QueryName="GetResourcesQuery" Width="0">
   2:     <riaControls:DomainDataSource.DomainContext>
   3:         <my:Test2008DomainContext />
   4:     </riaControls:DomainDataSource.DomainContext>
   5: </riaControls:DomainDataSource>  

Add a ListScheduleDataConnector in the Silverlight Application.

   1: <ig:ListScheduleDataConnector HorizontalAlignment="Left"  Name="listScheduleDataConnector1" VerticalAlignment="Top"  >
   2:     <ig:ListScheduleDataConnector.ResourcePropertyMappings>
   3:         <ig:ResourcePropertyMappingCollection UseDefaultMappings="True"/>                
   4:     </ig:ListScheduleDataConnector.ResourcePropertyMappings>
   5:     <ig:ListScheduleDataConnector.ResourceCalendarPropertyMappings>
   6:         <ig:ResourceCalendarPropertyMappingCollection UseDefaultMappings="True"/>
   7:     </ig:ListScheduleDataConnector.ResourceCalendarPropertyMappings>
   8:     <ig:ListScheduleDataConnector.AppointmentPropertyMappings>
   9:         <ig:AppointmentPropertyMappingCollection UseDefaultMappings="True"/>
  10:     </ig:ListScheduleDataConnector.AppointmentPropertyMappings>            
  11: </ig:ListScheduleDataConnector>

 

Implement a logic to load a data via DomainContext

In the constructor call a method InitializeXamSchedule that uses the DomainContext to call methods that returns Resources, ResourceCalendars and Appointments as IEnumerable.

   1: #region Constructors
   2: public MainPage()
   3: {
   4:     InitializeComponent();
   5:     InitializeXamSchedule(this.resourceDomainDataSource);
   6: }
   7: #endregion //Constructors
   8:  
   9: #region InitializeXamSchedule
  10: private void InitializeXamSchedule(object sender)
  11: {
  12:     this.xamDayView1.VisibleDates.Add(DateTime.Today.AddDays(-3));
  13:     this.xamDayView1.VisibleDates.Add(DateTime.Today.AddDays(-2));
  14:     this.xamDayView1.VisibleDates.Add(DateTime.Today.AddDays(-1));
  15:     this.xamDayView1.VisibleDates.Add(DateTime.Today.AddDays(1));
  16:     DomainDataSource src = sender as DomainDataSource;
  17:     if (src != null)
  18:     {
  19:         if (src.Equals(resourceDomainDataSource))
  20:         {
  21:  
  22:             Test2008DomainContext context = src.DomainContext as Test2008DomainContext;
  23:             if (context != null)
  24:             {
  25:  
  26:                 context.Load(context.GetResourcesQuery(),
  27:                              ResourcesLoadedCallback, null);
  28:                 context.Load(context.GetResourceCalendarsQuery(),
  29:                              ResourceCalendarsLoadedCallback, null);
  30:                 context.Load(context.GetAppointmentsQuery(),
  31:                              AppointmentsLoadedCallback, null);
  32:             }
  33:  
  34:         }
  35:     }
  36: }
  37: #endregion //InitializeXamSchedule

Create a callback methods to load Resources, ResourceCalendars and Appointments.
LoadOperation.Entities returns a read only collection. For features that you need to edit (like appointments) create a list using LoadOperation.Entities.ToList().

   1: #region AppointmentsLoadedCallback
   2: void AppointmentsLoadedCallback(LoadOperation<XamScheduleRiaDemoApp3.Web.Appointment> loadOperation)
   3: {
   4:     var appointments = loadOperation.Entities.ToList();
   5:     listScheduleDataConnector1.AppointmentItemsSource = appointments;
   6: }
   7: #endregion //AppointmentsLoadedCallback
   8:  
   9: #region ResourceCalendarsLoadedCallback
  10: void ResourceCalendarsLoadedCallback(LoadOperation<XamScheduleRiaDemoApp3.Web.ResourceCalendar> loadOperation)
  11: {
  12:     listScheduleDataConnector1.ResourceCalendarItemsSource = loadOperation.Entities;
  13: }
  14: #endregion //ResourceCalendarsLoadedCallback
  15:  
  16: #region ResourcesLoadedCallback
  17: void ResourcesLoadedCallback(LoadOperation<XamScheduleRiaDemoApp3.Web.Resource> loadOperation)
  18: {
  19:     listScheduleDataConnector1.ResourceItemsSource = loadOperation.Entities;
  20: }
  21: #endregion //ResourcesLoadedCallback

 

Add a XamScheduleDataManager.

   1: <ig:XamScheduleDataManager HorizontalAlignment="Left" Name="xamScheduleDataManager1"
   2:                VerticalAlignment="Top" DataConnector="{Binding ElementName=listScheduleDataConnector1}" CurrentUserId="mdour" 
   3:                                    Loaded="XamScheduleDataManager1Loaded"
   4:                                    ActivityAdded="XamScheduleDataManager1ActivityAdded" 
   5:                                    ActivityChanged="XamScheduleDataManager1ActivityChanged"
   6:                                    ActivityRemoved="XamScheduleDataManager1ActivityRemoved"/>
   7:         <StackPanel Orientation="Horizontal" Margin="0,10,0,0">

The logic in the event handler is described in the topic “Implement a logic to update appointments using XamScheduleDataManager events.“.

 

Add UI components from Schedule Suite: XamDayView, XamScheduleView, XamMonthView

Implementation is described in the article Implementing XamSchedule Solution in Silverlight Applications Using a WcfListDataConnector.

 

Implement a logic to update appointments using XamScheduleDataManager events.

Resources, ResourceCalendars and Appointment collections from DomainContext are not bound to the equal collections from ListScheduleDataConnector. The solution is to use XamScheduleDataManager events ActivityAdded, ActivityRemoved and ActivityRemoved and add a logic that updates the data source in their event handlers.

   1: #region XamScheduleDataManager1ActivityAdded
   2: private void XamScheduleDataManager1ActivityAdded(object sender, ActivityAddedEventArgs e)
   3: {
   4:     Test2008DomainContext cntx = this.resourceDomainDataSource.DomainContext as Test2008DomainContext;
   5:     if (cntx == null)
   6:     {
   7:         return;
   8:     }
   9:  
  10:     foreach (object x in listScheduleDataConnector1.AppointmentItemsSource)
  11:     {
  12:         Appointment app = x as Appointment;
  13:         if (app != null)
  14:         {
  15:             if (!cntx.Appointments.Contains(app))
  16:             {
  17:                 cntx.Appointments.Add(app);
  18:  
  19:  
  20:             }
  21:         }
  22:     }
  23:     cntx.SubmitChanges();
  24: }
  25: #endregion //XamScheduleDataManager1ActivityAdded
  26:  
  27: #region XamScheduleDataManager1ActivityChanged
  28: private void XamScheduleDataManager1ActivityChanged(object sender, ActivityChangedEventArgs e)
  29: {
  30:     this.resourceDomainDataSource.DomainContext.SubmitChanges();
  31: }
  32: #endregion //XamScheduleDataManager1ActivityChanged
  33:  
  34: #region XamScheduleDataManager1ActivityRemoved
  35: private void XamScheduleDataManager1ActivityRemoved(object sender, ActivityRemovedEventArgs e)
  36: {
  37:     this.resourceDomainDataSource.DomainContext.SubmitChanges();
  38: }
  39: #endregion //XamScheduleDataManager1ActivityRemoved
  40:  
  41: #region XamScheduleDataManager1Loaded
  42: private void XamScheduleDataManager1Loaded(object sender, RoutedEventArgs e)
  43: {
  44:     listScheduleDataConnector1.TimeZoneInfoProviderResolved.LocalTimeZoneId = "Jordan Standard Time";
  45: }
  46: #endregion //XamScheduleDataManager1Loaded

 

Implement a multi resource and multi calendar support.

Implementation is described in the article Implementing XamSchedule Solution in Silverlight Applications Using a WcfListDataConnector.

 

Implement a runtime change of the view type

Implementation is described in the article Implementing XamSchedule Solution in Silverlight Applications Using a WcfListDataConnector.

 

Implement a runtime support for calendar display mode.

Implementation is described in the article Implementing XamSchedule Solution in Silverlight Applications Using a WcfListDataConnector

 

Run the application:

All calendars owned from each of resources are displayed.

Change the current user to “Mike Dour”.

Change the current user to “Mihail Mateev”

Double click on the XamDayView to add an appointment.

Set duration to 30 minutes (from 11:00AM to 11:30AM)

Confirm appointment settings with “Save & Close” button.
A new appointment is added in the XamDayView  component.

Resize the last added appointment to make duration 1 hour (from 11:00AM to 12:00PM).

Select “All Calendars” button to display the calendars of all users.

Change the calendar display mode to “Overlay”.

Change the view type to “schedule view”.

When use a ListScheduleDataConnector with WCF RIA Services you have the same functionalities like when use the XamSchedule solution with a WcfScheduleDataConnector.
Articles for Infragistics scheduling suite demonstrates how you can use XamSchedule with different sources, based on different technologies in the same way.