A newer version of this page is available. Switch to the current version.

SchedulerControl.AllowAppointmentConflicts Event

Occurs when the scheduler finds appointments that are in conflict, and the SchedulerOptionsCustomization.AllowAppointmentConflicts property is set to Custom.

Namespace: DevExpress.XtraScheduler

Assembly: DevExpress.XtraScheduler.v19.1.dll

Declaration

public event AppointmentConflictEventHandler AllowAppointmentConflicts
Public Event AllowAppointmentConflicts As AppointmentConflictEventHandler

Event Data

The AllowAppointmentConflicts event's data class is AppointmentConflictEventArgs. The following properties provide information specific to this event:

Property Description
Appointment Gets the appointment for which the event was raised. Inherited from AppointmentEventArgs.
AppointmentClone Gets the clone of the appointment being processed in the SchedulerControl.AllowAppointmentConflicts or the SchedulerControl.AllowAppointmentConflicts events.
Conflicts Gets the collection of appointments which are considered to be conflicting with the current appointment.
Interval Gets the time interval which the event was raised for.

Remarks

Handle the AllowAppointmentConflicts event to manually decide whether the current appointment conflicts with any other appointments. The appointment copy to check can be accessed via the AppointmentEventArgs.Appointment property.

NOTE

The AllowAppointmentConflicts event is fired only if the SchedulerOptionsCustomization.AllowAppointmentConflicts property is set to AppointmentConflictsMode.Custom.

How to Signalize a Conflict

This event's arguments provide the AppointmentConflictEventArgs.Conflicts property, which returns the collection of appointments that are considered to be conflicting by the XtraScheduler. If the Conflicts collection is empty, this means that there are no conflicting appointments.

If you determine that the current appointment has no conflicts, you should clear the Conflicts collection in this event's handler. If you determine that the current appointment has at least one conflict, then the Conflicts collection should contain at least one object that is different from the current appointment. In other words, the source appointment (accessed via the AppointmentEventArgs.Appointment property) or its copy isn't considered to be conflicting if it's present in the Conflicts collection. There should be other appointments in this collection to indicate the conflict.

The non-empty Conflicts collection cancels the user action that caused the conflict. Common practice is to clear the Conflicts collection at the beginning, and populate it with any appointment if the user's action should be canceled. You can even create a fake appointment for this purpose, and add it to the collection.

What Properties to Analyze

The Appointment property of the AppointmentConflictEventArgs gets an appointment before modification.

The AppointmentConflictEventArgs.AppointmentClone property contains an appointment modified due to an end-user's action. If an appointment is being edited using standard or customized dialogs, the Appointment property is an appointment before the end-user dialog is initiated. The AppointmentClone property gets an appointment being modified by means of the end-user dialog.

In a drag operation, the AppointmentClone is the appointment that intersects with existing ones. The Appointment property provides access to the current appointment before modification. So, when an appointment is dragged, its clone may conflict with the original appointment, and the Conflicts collection may contain one element - the original appointment.

The following code snippet illustrates handling of the SchedulerControl.AllowAppointmentConflicts event for conflict resolution. When an appointment is modified or created, and the SchedulerOptionsCustomization.AllowAppointmentConflicts property is set to AppointmentConflictsMode.Custom, the AllowAppointmentConflicts event occurs. The code in the event handler checks whether the time interval of the modified appointment intersects with other appointments, including recurrent series and exceptions. If such an appointment is found, it is added to the AppointmentConflictEventArgs.Conflicts collection. If the collection has at least one element, a conflict occurs and the Scheduler cancels changes.

    // Concurrent appointments with the same resource are not allowed.
    scheduler.OptionsCustomization.AllowAppointmentConflicts = AppointmentConflictsMode.Custom;
    scheduler.AllowAppointmentConflicts += Scheduler_AllowAppointmentConflicts;

    scheduler.Storage.Appointments.Clear();
    scheduler.GroupType = SchedulerGroupType.Resource;
    Appointment apt1 = scheduler.Storage.Appointments.CreateAppointment(AppointmentType.Normal, DateTime.Now, DateTime.Now.AddHours(2));
    apt1.ResourceId = scheduler.Storage.Resources[0].Id;
    scheduler.Storage.Appointments.Add(apt1);
    Appointment apt2 = scheduler.Storage.Appointments.CreateAppointment(AppointmentType.Normal, DateTime.Now, DateTime.Now.AddHours(2));
    apt2.ResourceId = scheduler.Storage.Resources[1].Id;
    scheduler.Storage.Appointments.Add(apt2);
static void Scheduler_AllowAppointmentConflicts(object sender, AppointmentConflictEventArgs e) {
    e.Conflicts.Clear();
    FillConflictedAppointmentsCollection(e.Conflicts, e.Interval, ((SchedulerControl)sender).Storage.Appointments.Items, e.AppointmentClone);
}
static void FillConflictedAppointmentsCollection(AppointmentBaseCollection conflicts, TimeInterval interval,
    AppointmentBaseCollection collection, Appointment currApt) {
    for (int i = 0; i < collection.Count; i++) {
        Appointment apt = collection[i];
        if (new TimeInterval(apt.Start, apt.End).IntersectsWith(interval) & !(apt.Start == interval.End || apt.End == interval.Start)) {
            if (Object.Equals(apt.ResourceId, currApt.ResourceId)) {
                conflicts.Add(apt);
            }
        }
        if (apt.Type == AppointmentType.Pattern) {
            FillConflictedAppointmentsCollection(conflicts, interval, apt.GetExceptions(), currApt);
        }
    }
}

The appointment editing form in its OnOkButton method checks for appointment conflicts using the AppointmentFormControllerBase.IsConflictResolved method. If it returns false, the edited appointment cannot be saved and a proper message appears. This message text can be modified by the Localizer technique, i.e., overriding the Localizer.GetLocalizedString method in a SchedulerLocalizer descendant, and specifying the required text for the SchedulerStringId.Msg_Conflict identifier. Please review the Localizing WinForms Controls via Localizer Objects document, for more information.

See Also