WinForms - Scheduler - Synchronization With Google Calendars

02 April 2019

Since v18.2 was released several months ago, you might have already tried our new Scheduler synchronization with Google Calendars. We’d love to hear your feedback on this feature! But first, let’s look at it in some detail in case you’ve missed it so far.

DXGoogleCalendarSync Component

To synchronize Scheduler and Google Calendars Appointments (in Google documentation, these are referred to as Events), you need a DXGoogleCalendarSync component. The Scheduler automatically adds it when you click the Add DX Google Calendar Synchronizer Smart Tag link. The component requires several NuGet packages.

Add DX Google Calendar Synchronizer

DXGoogleCalendarSync transfers data between a Scheduler Storage (both SchedulerDataStorage and its predecessor SchedulerStorage are supported) and a selected Google Calendar. The Storage can be bound to any supported data source at the same time.

Component Relations

You are not limited to either importing or exporting data. Synchronization is a two-way process that handles both tasks at the same time.

Limitations

The DXGoogleCalendarSync component correctly recognizes and synchronizes all Appointment types supported in Scheduler: regular and recurring appointments, all-day events, holidays, etc. The only type of content that the component cannot sync automatically is color information: Appointment Labels and Statuses are not converted into Event Colors and vice versa by default. A Status is a unique Appointment attribute that has no matching Event property (Google Events provide only two “statuses” - Busy and Free). You can sync Labels manually with Event colors by handling certain component events (see this GitHub example).

The second limitation is that the DXGoogleCalendarSync can only work with one calendar at a time, while a Google Calendars user can subscribe to multiple different calendars: Personal, Work, Vacations, Family, a corporate calendar shared between colleagues, and more. Of course you can easily retrieve a list of calendars and implement a UI to switch between them at runtime.

Technical Details

This GitHub example shows the sync component in action.

To manage Google Calendar Events you need access to the Google Calendar API. Please click this link for the Quickstart page in the Google documentation and follows steps 1 to 3b to download your own credentials.json file. This should be included in your project. The GitHub sample uses the name client_secret.json for this file.

There are three core properties that need to be set on the component.

  • Storage - a Scheduler Storage object that stores Appointments. In the sample, this property is assigned at design time (see here)
gcSyncComponent.Storage = schedulerStorage;
  • CalendarService - a Google Calendar Service that allows the component to access and modify calendars. The current user must be authorized for access to the Google account (here is the sample method AuthorizeToGoogle).
...
GoogleWebAuthorizationBroker.AuthorizeAsync(
  GoogleClientSecrets.Load(stream).Secrets,
  new String[] { CalendarService.Scope.Calendar },
  "user",
  CancellationToken.None,
  new FileDataStore(credPath, true));

Then the CalendarService can be instantiated (in OnLoad in the sample).

...
gcSyncComponent.CalendarService =
  new CalendarService(new BaseClientService.Initializer() {
    HttpClientInitializer = this.credential,
    ApplicationName = "GoogleCalendarSyncSample"
  });
...
  • CalendarID - the Google Calendar identifier for the sync. Here is some sample code that retrieves all Google Calendars and populates a combo box. You can then handle the SelectedIndexChanged combo box event to assign valid IDs to the CalendarID property.
CalendarList calendarList;
string activeCalendarId;

async Task UpdateCalendarListUI() {
  var listRequest = this.service.CalendarList.List();
  this.calendarList = await listRequest.ExecuteAsync();
  this.ricbCalendarList.Items.Clear();

  foreach (CalendarListEntry item in this.calendarList.Items)
    this.ricbCalendarList.Items.Add(item.Summary);

  if (!String.IsNullOrEmpty(this.activeCalendarId)) {
    var itemToSelect = this.calendarList.Items.FirstOrDefault(
      x => x.Id == this.activeCalendarId);
    this.gcSyncComponent.CalendarId = this.activeCalendarId;

    if (this.ricbCalendarList.Items.Contains(itemToSelect.Summary))
      this.beiCalendarList.EditValue = itemToSelect.Summary;
    else
      this.activeCalendarId = String.Empty;
  }
}

When everything is set up, call Synchronize or SynchronizeAsync on the DXGoogleCalendarSync component to trigger the synchronization process at any time. On first launch, your default web browser will show a page asking you to log into the Google account you want to use for the sync.

Beyond the basic setup described above, the DXGoogleCalendarSync component provides other features, including these:

  • Session state logging to help prioritize Scheduler Appointments vs Google Events
  • A dedicated event fires when a minor sync conflict occurs. Handle it to determine validity manually.
  • Custom fields to store Google Event ID and eTag values
  • The ProgressChanged event to track synchronization state for custom progress indicators

For full documentation of the Google Calendar synchronization features, please visit this link.

We want to hear from you!

Please let us know what you think. Have you tried this feature yet? Are you planning to use it in the future? Is there some extra functionality you require?

10 comment(s)
Lluis Franco

Great news Oliver! :)

Do you have plans to also add Office365 sync?

2 April, 2019
Orhan ÖCAL

Great news! Very well...

2 April, 2019
Oliver Sturm (DevExpress)

Lluis - no immediate plans, but we'll keep an eye on the suggestion. Here are some details: https://www.devexpress.com/Support/Center/Question/Details/T341117/sync-between-schedule-and-office-365

Thank you!

2 April, 2019
Nate Laff

Can this work with multiple resources? (i.e. each resource as an person that has their own google calendar?) and is there some background sync component?

2 April, 2019
Mojo

+1 for Office 365 support.

2 April, 2019
Engº Silvio Cruz

+1 for Office 365 support.

2 April, 2019
Jeff Stiegler

We will not be using this feature because we believe that Google does not respect a person's privacy.

Add us to the +1 Office 365 support movement.

3 April, 2019
Dmitry Babich (DevExpress)

Nate - these features are not supported at the moment. Currently, we are collecting user feedback and will probably implement them in the future.

5 April, 2019
Nate Laff

Thanks Dmitry, I would require both :) Thanks!

5 April, 2019
Linton

+1 Office 365 support

9 April, 2019

Please login or register to post comments.