This topic presents an overview of the Scheduler's event model, describing the order in which events are raised.
Persistent objects publish two categories of data-related events.
The first set includes events that are raised before the action takes place. They are usually named with the "ing" ending, and are used for pre-processing and cancelling the action. In this case, an event handler receives one object that has already been modified. If you set the Cancel parameter to true, the modification is rolled back.
Several events do not enable you to get the object in the unmodified state, so you will have to query the corresponding data object directly to obtain property values before modification.
Then, there are events in this category that receive both the original and the changed objects. For example, the SchedulerControl.AppointmentDrag event receives both the AppointmentDragEventArgs.EditedAppointment and AppointmentDragEventArgs.SourceAppointment objects. You should clearly distinguish these two objects when handling this event.
The second set of events includes events with the "ed" ending, which are fired when the action has been performed. They provide notification and post-processing.
The two events that correspond to one action, and belong to different categories form an event pair. Events for AppointmentBaseCollection and ResourceBaseCollection collections, in contrast to single objects, do not come in pairs.
Guidelines for correct event handling are listed below:
- A good practice is to use PersistentObject.BeginUpdate/ PersistentObject.EndUpdate blocks, because it reduces the time required for initialization, and prevents raising events excessively. It is especially effective when event handling takes a considerable amount of time.
- Do not remove the object instance for which the first event in a pair is fired (the "ing" event). Its properties can be changed within the BeginUpdate / EndUpdate block. Deleting an object in the middle of this action, in between events, can result in some hard-to-find errors.
- Take special note of explicit SchedulerStorageBase.RefreshData calls. Data will be reloaded, and all custom field values that are not mapped will be lost. In particular, this may happen when a SchedulerStorage operates in unbound mode.
- When handling the SchedulerStorageBase.FetchAppointments event, change data in the data source at the Data layer. Do not modify data at the Storage layer, because the Storage automatically reloads its data from the Data layer's data source when this event handler is executed.
- When the data source is changed, and the PersistentObjectStorage<T>.AutoReload property is set to true, the SchedulerStorageBase.AppointmentCollectionAutoReloading event occurs, and the Storage starts an automatic refresh. Use the SchedulerStorageBase.AppointmentCollectionAutoReloading event as a notification.
The order of events raised in typical situations is illustrated in the following table:
Action
|
Order in which events fire
|
Notes
|
Scheduler View initialization |
SchedulerStorageBase.AppointmentCollectionAutoReloading, SchedulerStorageBase.AppointmentCollectionLoaded, SchedulerStorageBase.FetchAppointments, SchedulerStorageBase.FilterAppointment*
|
|
Visible interval modification of a View or a Control |
SchedulerStorageBase.FetchAppointments, SchedulerStorageBase.FilterAppointment*
|
|
Clearing the PersistentObjectStorage
|
SchedulerStorageBase.AppointmentCollectionCleared |
|
PersistentObjectStorage.DataSource substitution
|
SchedulerStorageBase.AppointmentCollectionLoaded
|
|
Adding a new appointment to a collection
|
SchedulerStorageBase.AppointmentInserting, SchedulerStorageBase.AppointmentsInserted, SchedulerStorageBase.FilterAppointment*
|
|
Occurrence appointments modification, resulting in exceptions for a particular recurrence pattern.
|
SchedulerStorageBase.AppointmentChanging, SchedulerStorageBase.AppointmentsInserted, SchedulerStorageBase.AppointmentsChanged, SchedulerStorageBase.FilterAppointment |
The SchedulerStorageBase.AppointmentsInserted event is raised for the newly created AppointmentType.ChangedOccurrence.
|
Occurrence appointments removal, resulting in exceptions for a particular recurrence pattern.
|
SchedulerStorageBase.AppointmentDeleting, SchedulerStorageBase.AppointmentsInserted, SchedulerStorageBase.FilterAppointment* |
The SchedulerStorageBase.AppointmentsInserted event is raised for the newly created AppointmentType.DeletedOccurrence.
|
Removing a pattern with two exceptions
|
SchedulerStorageBase.AppointmentDeleting, AppointmentDeleting, AppointmentDeleting, SchedulerStorageBase.AppointmentsDeleted, SchedulerStorageBase.FilterAppointment* |
The SchedulerStorageBase.AppointmentDeleting event is first raised for the pattern and then - for all its exceptions. Note: if deleting of an exception is cancelled, the entire process is cancelled, and nothing is deleted.
|
Modification of three appointments at once with an action cancelled for one of them (e.g. drag-move)
|
SchedulerStorageBase.AppointmentChanging, AppointmentChanging, AppointmentChanging, SchedulerStorageBase.AppointmentsChanged |
The SchedulerStorageBase.AppointmentChanging event is raised three times (one for each appointment). The action is cancelled in one of them. In the SchedulerStorageBase.AppointmentsChanged event, we have only two modified appointments.
|
* If the filter is applied, the SchedulerStorageBase.FilterAppointment event is raised for each appointment that falls within the visible interval.