This is a migrated thread and some comments may be shown as answers.

Detect dropping appointment on another

9 Answers 256 Views
ScheduleView
This is a migrated thread and some comments may be shown as answers.
This question is locked. New answers and comments are not allowed.
Håkan
Top achievements
Rank 1
Håkan asked on 11 Nov 2011, 02:44 PM
Hi,

I use timeline view with resource grouping and snap appointments (see attached image).
The appointments fill up a whole day.
The appointments can be dragged between different days for the same resource or even between different resources.

I need to detect on drop, if I drop the appointment on a slot that alredy contains an appointment or if it is empty.
How can I do that?

I have a custom DragDropBehavior that looks like this:
public class CustomDragDropBehavior : ScheduleViewDragDropBehavior
   {
       public event EventHandler<EventArgs<TimeScheduleShift>> NewShiftDropped;
 
       public override void Drop(DragDropState state)
       {
           if (state.IsControlPressed)
           {
               // TODO: Copy shift
           }
 
           if (state.SourceAppointmentsSource == state.DestinationAppointmentsSource)
           {
               if (state.Appointment != null && state.DestinationSlots.Count() > 0)
               {
                   // Get dragged shift
                   TimeScheduleShift shift = state.Appointment as TimeScheduleShift;
                   if (shift != null)
                   {
                       // Get destionation slot (where shift is dropped)
                       DragDropSlot slot = state.DestinationSlots.First() as DragDropSlot;
                       if (slot != null && slot.Resources.Count() > 0)
                       {
                           // Get destination slot's employee
                           TimeScheduleEmployeeResource employee = slot.Resources.First() as TimeScheduleEmployeeResource;
                           if (employee != null)
                           {
                               // Check if destination employee is different from source employee
                               int employeeId = 0;
                               Int32.TryParse(employee.ResourceName, out employeeId);
                               if (employeeId != 0 && employeeId != shift.EmployeeId)
                                   shift.EmployeeId = employeeId;
                           }
                       }
                   }
               }
 
               base.Drop(state);
           }
           else
           {
               // Get dropped shift
               var newShift = state.Appointment as TimeScheduleShift;
               // Get time slot where shift was dropped
               Slot droppedAtSlot = state.DestinationSlots.First();
 
               // Calculate offset between default shift start and actual dropped at start
               TimeSpan offset = droppedAtSlot.Start - newShift.Start;
               // Set new times based on dropped time
               newShift.Start = newShift.Start.Add(offset);
               if (newShift.BreakStart.HasValue)
                   newShift.BreakStart = newShift.BreakStart.Value.Add(offset);
               if (newShift.BreakStop.HasValue)
                   newShift.BreakStop = newShift.BreakStop.Value.Add(offset);
               newShift.End = newShift.End.Add(offset);
               newShift.ActualStart = newShift.Start;
               newShift.ActualEnd = newShift.End;
 
               // Add shift to collection
               (state.DestinationAppointmentsSource as ObservableCollection<TimeScheduleShift>).Add(newShift);
 
               if (NewShiftDropped != null)
                   NewShiftDropped(this, new EventArgs<TimeScheduleShift>(newShift));
           }
       }
   }

In this code I can find out if I dropped the appointment on another resource (Employee) and change it's ID.
But I also need to find out if the destination slot already contained an appointment before the drop.

Regards,
HÃ¥kan


9 Answers, 1 is accepted

Sort by
0
Yana
Telerik team
answered on 16 Nov 2011, 12:20 PM
Hello HÃ¥kan,

Please find attached a simple example which implements how you can implement ConflictCheckingBehavior in RadScheduleView. Download it and give it a try.

Hope this helps.

Greetings,
Yana
the Telerik team

Explore the entire Telerik portfolio by downloading the Ultimate Collection trial package. Get it now >>

0
Håkan
Top achievements
Rank 1
answered on 05 Jan 2012, 11:58 AM
Hi Yana!

I tried your example and it works as it is designed for, but in my case I do not want to prevent drag/drop over existing appointments, but I want to detect it.

In my CustomDragDropBehavior I have overridden the Drop event and from the DragDropState I can get a hold of both the dropped appointment and the slot I drop it in, but I can't seem to find out if there are any existing appointments in that slot.
From state.DestinationAppointmentsSource I get all appointments in my view, not only in the slot.

I guess I can check the Resources and the time span but there must be an easier way?
Since you have made your example work so easy, it's almost what I want.
I guess I don't have enought knowledge of LINQ to manage it.

To make it harder (maybe).
My slots can contain several appointment on the same resource and time frame.
And I would (if it is possible) like to detect exactly which appointment I drop on.
In that case it is not enought to just check the resource and timespan, I guess I have to check the mouse pointer or something?

Do you have any ideas?

Regards,
HÃ¥kan
0
Yana
Telerik team
answered on 06 Jan 2012, 12:32 PM
Hi HÃ¥kan,

You can get the appointments in the slot in Drop event like this:

public override void Drop(DragDropState state)
{
    var appsInTheSlot = state.DestinationSlots.SelectMany(sl => state.DestinationAppointmentsSource
        .OfType<IAppointment>()
        .Where(a => a.IntersectsWith(sl) && !state.DraggedAppointments.Contains(a)));
 
    base.Drop(state);
}

Please try it and let us know whether it helps.

All the best,
Yana
the Telerik team

Explore the entire Telerik portfolio by downloading the Ultimate Collection trial package. Get it now >>

0
Håkan
Top achievements
Rank 1
answered on 09 Jan 2012, 10:26 AM
Hi Yana!

Thanks for the code example, it almost worked.
My view is grouped on Resource also, so with this code I get all appointments for that slot, regardless of resource.
I want only the appointment in the slot belonging to the target resource also.

Is that possible?

Regards,
HÃ¥kan
0
Yana
Telerik team
answered on 09 Jan 2012, 03:55 PM
Hello HÃ¥kan,

Please modify the method like this:

public override void Drop(DragDropState state)
{
    var res = state.DestinationSlots.SelectMany(sl => state.DestinationAppointmentsSource
        .OfType<IAppointment>()
        .Where(a => this.AreOverlapping(a,sl) && !state.DraggedAppointments.Contains(a)));
    base.Drop(state);
}

and add the AreOverlapping and AreIntersected methods to the CustomDragDropBehavior class:

private static bool AreIntersected(IEnumerable<IResource> first, IEnumerable<IResource> other)
{
    IEnumerable<IResource> firstResources = first
        .Distinct();
 
    IEnumerable<IResource> otherResources = other              
        .Distinct();
 
    return firstResources.Where((IResource r) => otherResources.Contains(r)).Count() == firstResources.Count();
}
 
private bool AreOverlapping(IAppointment appointment, Slot slot)
{
    return appointment.IntersectsWith(slot) && AreIntersected(appointment.Resources.OfType<IResource>(), slot.Resources.OfType<IResource>());          
}

Hope it's ok now.

All the best,
Yana
the Telerik team

Explore the entire Telerik portfolio by downloading the Ultimate Collection trial package. Get it now >>

0
Håkan
Top achievements
Rank 1
answered on 10 Jan 2012, 09:58 AM
Hi Yana!

That did the trick, thanks!
I have one more question though...

In my TimelineView every slot is one whole day and the appointments fill up the whole day graphically even if its actual time range is less.

To the problem:
Lets say one resource have two appointments in the same slot, one can for example be 07:00-11:00 and another 11:00-16:00. Both appoinments fill up the whole slot in width and are placed below each other (see attached image). And that is exactly how we want to display them.

The problem occurs if I drag another appointment into this slot and drop in on top of one of these existing appointments, I want to detect exactly which appoinment it was dropped on (need to show a dialog with a question if it should replace the existing).
Is there anyway I can detect which appointment that was under the mouse pointer when I drop it.
From the Drop event I can get the slot and both appoinments, but not the exact appointment it was dropped on, or...?

If it doesn't work, I guess I have to check the actual time range on the dragged appointment and compare it to the appointments in the dropped slot, if any one is overlapping I can take it. The problem then is that both may be overlapping or intersecting...

Regards,
HÃ¥kan

0
Yana
Telerik team
answered on 12 Jan 2012, 04:08 PM
Hello HÃ¥kan,

Currently you cannot find the exact location on which the appointment is dropped.  You can get only the Slot and the appointments in it.

We are sorry for the inconvenience and hope this is not a show stopper for you.

All the best,
Yana
the Telerik team

Explore the entire Telerik portfolio by downloading the Ultimate Collection trial package. Get it now >>

0
Sally
Top achievements
Rank 1
answered on 25 Jun 2012, 01:20 PM
Yana,

Is there a way to detect if the DragDropState.DestinationSlots are Overlapping with a SpecialSlot (not an Appointment) on the ScheduleView? The DragDropState doesn't seem to contain any SpecialSlot information, it only contains the Appointments on the ScheduleView.   I would like to write code in the CanDrop function based on the SpecialSlot the dragged appointment is currently overlapping.  

Thanks,
Sally
0
Yana
Telerik team
answered on 28 Jun 2012, 12:31 PM
Hello Sally,

This is correct - DragDropState does not contain information about the SpecialSlots and I am afraid that the required approach cannot be easily achieved with RadScheduleView.

All the best,
Yana
the Telerik team

Explore the entire Telerik portfolio by downloading the Ultimate Collection trial package. Get it now >>

Tags
ScheduleView
Asked by
Håkan
Top achievements
Rank 1
Answers by
Yana
Telerik team
Håkan
Top achievements
Rank 1
Sally
Top achievements
Rank 1
Share this question
or