Articles and Tutorials

How to use Calendar Control Custom Data Provider

Author: Sergey Sinkevich
Platform: Visual Basic 6.0

Introduction

This article shows how to use a custom data source for the Calendar control. It is described basing on MySQL database provider sample which is included into standard Visual Basic CalendarSample application.

Background

Calendar control has built-in support for the following data providers: Memory, XML file (or binary file), Database (Access), MAPI (Outlook).

However, many people already have their own sources for data to be displayed in a Calendar window. This could be a legacy database which does not support Codejock Calendar database model, this could be a specific database server (Microsoft SQL Server, MySQL, FoxPro, etc), this could be even a custom memory array of appointments data objects which already has an own load/save code.

Another problem is how to allow a number of people to work simultaneously with the same set of appointments on different workstations (note that it might be only partially solved with the described solution).

And the third problem is when people have a very lot of appointments data and suspect that it might be a problem to hold all their data in memory simultaneously.

All those problems could be resolved with implementing your Custom Calendar Data Provider.

Simple solution -- custom load/save events code

Let's firstly consider a simplest case -- you have a legacy database and just want to work with it on the single workstation, and you want to open and save all the changes with corresponding toolbar buttons (or any other way, the main idea is that database in not always synchronized with those which is show on the Calendar).

In this case the correct solution for you would be not to use a Custom Data Provider at all :)

All that you need is to use the standard Memory Data Provider, which is created with the Calendar control by default. Of course, it could be serialized into XML file, but if you do not provide the file name, Memory Data Provider will be a simple storage for your Events. You'll have to Populate the Calendar with your Events, and then allow user to work with them, and update all the data in the database on the moment of saving by iterating all Calendar Events. This might look in a following way:

Load:

' Load events
Sub Populate()
        objCalendar.DataProvider.RemoveAllEvents
 
    ' <open events recordset or collection>
    ' <iterate this collection>
        For each objEvent in objEventsCollection
        Set objCalendarEvent = objCalendar.DataProvider.CreateEventEx(objEvent.ID)
 
        objCalendarEvent.StartTime = ...
        ...
 
        objCalendar.DataProvider.AddEvent objCalendarEvent    
    Next
 
    objCalendar.Populate
End Sub

Save:

' Iterate events and save into a database
Private Sub Save()
    Dim objEvent As CalendarEvent
    For Each objEvent In objCalendar.DataProvider.GetAllEventsRaw
        ' <save Event properties>
        'objEvent.Id
        'objEvent.Subject
    Next
    ' <commit save>
End Sub

Complex solution -- custom data provider

    CalendarControl.SetDataProvider "Provider=Custom;"

Custom data provider is what you need when you have own source for data to be displayed (like DB or memory collection), when you have a throng of appointment records, or when you'd like to have a multi-user working environment.

There are already a couple of standard samples available (for MS SQL Server and for MySQL).

Briefly about how it works: it asks you to create/read/update calendar events in the data source. When you set Custom data provider - Calendar send some notifications which you have to catch and process operations with data: like read event data from DB and fill calendar event object members or update/create/delete DB record.

You can use any database or other custom data storage (like objects array, etc).

With the custom data provider the main thing you should implement is the body of RetrieveDayEvents handler. If it returns empty events collection, the control will always show nothing.

The second major thing to implement is the body of DoXXX handlers. For a detailed code examples, see VB CalendarSample, classes providerMySQL.cls and providerSQLServer.cls.

Creation of a new Event:

Private Sub Calendar_DoCreateEvent(ByVal pEvent As _
            XtremeCalendarControl.CalendarEvent, NewEventID _
            As Long, bResult As Boolean)
    ' 1) get properties from pEvent
    ' 2) prepare and execute corresponding SQL statement which adds
    '    a new event into a database
    ' 3) if database has auto incrementing EventID field, retrieve 
    '    it for a new event and assign into NewEventID
    ' 4) set bResult to True if all operations successfully finished    
End Sub

About a recurrence

When custom data provider asks you to read an event or an events set, you have to read only events with "notRecurring" or "master" recurrence state.

When you're loading recurrence pattern you also have to load and set all calendar event exceptions related to this pattern.

Loading recurrence master event

There is a trick when you're reading calendar event object with "master" recurrence state and return it to custom data provider.

There are 2 special custom properties for calendar event object: "process_RecurrenceState" and "process_RecurrencePatternID". They are used to process master events.

If they are set and RecurrenceState is "master" � the custom Data provider will fire DoReadRPattern event and make event as Master. And it will also generate occurrences for RetrieveDayEvents method.

These properties are temporary and they will be removed by data provider.

If these properties are not set � custom data provider expects that master event is already completed - CreateRecurrence method is called and Recurrence pattern is set.

This mechanism is useful for DB data providers, when events and patterns are stored separately (in different tables).

But if events stored in some memory collection or array it should not be used because master event stores recurrence pattern inside.

Articles and Tutorials