WPF - Scheduler - New Drag&Drop Events (v19.1)

WPF Team Blog
26 April 2019

We have some great news for those who asked us for advanced drag&drop customization features in the WPF Scheduler. We had requests for the following functionality:

  • To provide control over an ongoing drag&drop operation
  • To simplify event data and make it more consistent across different operations
  • To customize visual feedback during a drag&drop operation
  • To implement dragging to or from an external control or application

To facilitate all this, we redesigned our drag&drop engine for v19.1. New events are now available that give you control over drag&drop operations at all stages.

Note: The new events logically replace SchedulerControl.AppointmentDrag and SchedulerControl.AppointmentDrop. These two old events will remain in place for backwards compatibility. However, you cannot use a mix of old and new events and you will see exceptions thrown by the SchedulerControl if you do.

Here is a diagram of the new event flow:

Scheduler Drag&Drop Event Flow

Internal Drag&Drop

An ongoing scheduler-internal drag operation is controlled by three events, each suited to specific tasks.

  1. The event QueryContinueAppointmentDrag lets you handle user actions
  2. The event DragAppointmentOver is used to process appointments under the cursor, to detect and resolve conflicts
  3. Finally, the event GiveAppointmentDragFeedback allows you to change the cursor style for visual feedback

Each event has its own set of parameters. This structure makes it easier to develop and test customizations for drag&drop operations.

Here is an example implementation. With the help of the new events, the code detects when dragged appointments conflict with others and indicates the problem by assigning a label.

private void Scheduler_DragAppointmentOver(object sender,
  DragAppointmentOverEventArgs e) {
  // if a dragged appointment intersects with another appointment,
  // paint it red to indicate a conflict
  for (int i = 0; i < e.ConflictedAppointments.Count; i++)
    if (e.ConflictedAppointments[i].Count > 0)
      e.DragAppointments[i].LabelId = 1;

  // reset the label if no conflicts are detected
  for (int j = 0; j < e.ConflictedAppointments.Count; j++)
    if (e.ConflictedAppointments[j].Count == 0)
      e.DragAppointments[j].LabelId = e.SourceAppointments[j].LabelId;
}

private void Scheduler_DropAppointment(object sender, DropAppointmentEventArgs e) {
  for (int i = 0; i < e.DragAppointments.Count; i++) {
    // if a dragged appointment has no conflicts
    if (e.ConflictedAppointments[i].Count == 0) {
      // it can be moved to the target position
      e.SourceAppointments[i].Start = e.DragAppointments[i].Start;
      e.SourceAppointments[i].End = e.DragAppointments[i].End;
    }
  }
}

Internal Drag&Drop

External Drag&Drop

As you can also see in the diagram above, external drag operations have their own event flow – whether they originate from other controls in the same application or even from other applications.

The following code implements the required logic to accept drags from a GridControl instance, as well as others that support a string format.

private void Scheduler_StartAppointmentDragFromOutside(object sender,
  StartAppointmentDragFromOutsideEventArgs e) {

  // if the user is dragging GridControl data
  if (e.Data.GetDataPresent(typeof(RecordDragDropData))) {
    var rddData = (RecordDragDropData) e.Data.GetData(typeof(RecordDragDropData));
    foreach (var appData in rddData.Records.Cast<AppointmentData>()) {
      var appointment = new AppointmentItem {
        Subject = appData.Subject,
        Location = appData.Location
      };
      appointment.End = appointment.Start + appData.Length;
      e.DragAppointments.Add(appointment);
    }
  }

  // if the user is dragging text
  if (e.Data.GetDataPresent(typeof(string))) {
    var subject = (string) e.Data.GetData(typeof(string));
    var appointment = new AppointmentItem { Subject = subject };
    e.DragAppointments.Add(appointment);
  }
}

External Drag&Drop

Your Thoughts Count

The new drag&drop engine makes it much more convenient for us to add new events or expand existing ones. Please let us know what you think about the new features, or if you have any additional requests.

Free DevExpress Products - Get Your Copy Today

The following free DevExpress product offers remain available. Should you have any questions about the free offers below, please submit a ticket via the DevExpress Support Center at your convenience. We'll be happy to follow-up.
No Comments

Please login or register to post comments.