Ioan Crisan
Top achievements
Rank 1
Ioan Crisan
asked on 27 Oct 2012, 02:05 PM
Hi there,
I have the following problem: I have a list of persons and a ScheduleView displaying appointments. I need to drag persons over an appointment to associate those persons with the appointment. I tried to search for solutions to this problem but at no avail. The ScheduleView wants always to add a new appointment, which I actually want to forbid.
Could you please provide me an example of how can I solve this requirement?
Thanks,
Ioan
I have the following problem: I have a list of persons and a ScheduleView displaying appointments. I need to drag persons over an appointment to associate those persons with the appointment. I tried to search for solutions to this problem but at no avail. The ScheduleView wants always to add a new appointment, which I actually want to forbid.
Could you please provide me an example of how can I solve this requirement?
Thanks,
Ioan
8 Answers, 1 is accepted
0
Hello Ioan,
First, I would suggest to use RadListBox to hold the Person objects. Then you can easily implement drag and drop between RadListBox and RadScheduleView - the approach is explained in details here.
Also you can use the approach demonstrated in this Code Library (it's the same for Silverlight) to find whether the destination slot contains any appointments. If there is an appointment, update the needed properties.
Please try it and if you have any additional issues, contact us again.
All the best,
Yana
the Telerik team
First, I would suggest to use RadListBox to hold the Person objects. Then you can easily implement drag and drop between RadListBox and RadScheduleView - the approach is explained in details here.
Also you can use the approach demonstrated in this Code Library (it's the same for Silverlight) to find whether the destination slot contains any appointments. If there is an appointment, update the needed properties.
Please try it and if you have any additional issues, contact us again.
All the best,
Yana
the Telerik team
Explore the entire Telerik portfolio by downloading Telerik DevCraft Ultimate.
0
A
Top achievements
Rank 1
answered on 14 Nov 2012, 03:47 AM
Hello loan
did you find any solution? i am facing same kind of problem and i want to add resources to appointments by dropping them from RadListView to the appointment itself in RadScheduleView.
please let us know if you succeed in implementing the solution.
Thx
Ali
did you find any solution? i am facing same kind of problem and i want to add resources to appointments by dropping them from RadListView to the appointment itself in RadScheduleView.
please let us know if you succeed in implementing the solution.
Thx
Ali
0
Ioan Crisan
Top achievements
Rank 1
answered on 14 Nov 2012, 08:05 PM
Hi Ali,
I have a partial solution, which is not satisfactory for the end customer. I mean I can drop persons in the scheduler, but if there are more appointments scheduled at the same time I did not find any way to differentiate among them. By the way: do not forget to add a behavior to the person list also (in my case) so that the items are not removed on move. Below you have the code snippets.
@Yana: Could you provide me a code snippet to differentiate among the slots the user dropped the item? There is no information whatsoever in the method arguments to be able to do that. Moreover, it is somehow funny to check in all available slots if there are intersecting appointments - a property in the DragDropState indicating on which appointments is dropped would be ideal.
I have a partial solution, which is not satisfactory for the end customer. I mean I can drop persons in the scheduler, but if there are more appointments scheduled at the same time I did not find any way to differentiate among them. By the way: do not forget to add a behavior to the person list also (in my case) so that the items are not removed on move. Below you have the code snippets.
@Yana: Could you provide me a code snippet to differentiate among the slots the user dropped the item? There is no information whatsoever in the method arguments to be able to do that. Moreover, it is somehow funny to check in all available slots if there are intersecting appointments - a property in the DragDropState indicating on which appointments is dropped would be ideal.
using
System.Linq;
using
Primary.StudioAssistant.Contacts.Domain.Default;
using
Telerik.Windows.DragDrop.Behaviors;
namespace
Primary.StudioAssistant.Core.Studio.Views.Default
{
public
class
AttendancesListDragDropBehavior : ListBoxDragDropBehavior
{
/// <summary>
/// Returns true if the dragged items should be removed from the source list, otherwise false.
/// </summary>
/// <param name="state">DragDropState that provides context for the current operation.</param>
protected
override
bool
IsMovingItems(DragDropState state)
{
return
false
;
}
}
}
using
System;
using
System.Collections;
using
System.Collections.Generic;
using
System.Linq;
using
Kephas;
using
Kephas.Model;
using
Primary.StudioAssistant.Contacts.Domain.Default;
using
Telerik.Windows.Controls;
using
Telerik.Windows.Controls.ScheduleView;
using
Telerik.Windows.DragDrop.Behaviors;
using
DragDropState = Telerik.Windows.Controls.DragDropState;
using
Resource = Telerik.Windows.Controls.Resource;
namespace
Primary.StudioAssistant.Scheduling.Views.Default
{
/// <summary>
/// TODO: Update summary.
/// </summary>
public
class
AssociatePersonDragDropBehavior : ScheduleViewDragDropBehavior
{
public
override
IEnumerable<IOccurrence> ConvertDraggedData(
object
data)
{
var payload = data
as
IDragPayload;
if
(payload ==
null
)
return
new
IOccurrence[0];
var format =
typeof
(IStudentAttendance).FullName;
var attendances = payload.GetData(format)
as
IEnumerable;
if
(attendances ==
null
)
return
new
IOccurrence[0];
var attendance = attendances.OfType<IStudentAttendance>().FirstOrDefault();
if
(attendance ==
null
)
return
new
IOccurrence[0];
// create dummy new appointment with a duration of 1 minute. It should display as a line.
var appointment =
new
Appointment
{
Subject = attendance.Person.ToString(),
RecurrenceRule =
null
,
Start = DateTime.Today,
End = DateTime.Today.AddMinutes(1),
};
appointment.Resources.Add(
new
TaggedResource { Tag = attendance });
return
new
IOccurrence[] { appointment };
}
public
override
bool
CanDrop(DragDropState state)
{
var canDrop = state.DestinationAppointmentsSource
.OfType<IAppointment>()
.Where(a => !state.DraggedAppointments.Contains(a))
.Any(a => state.DestinationSlots.Any(s => ConflictChecking.AreOverlapping(a, s)));
return
canDrop;
}
public
override
bool
CanResize(DragDropState state)
{
return
state.DestinationAppointmentsSource
.OfType<IAppointment>()
.Where(a => a != state.Appointment)
.All(a => state.DestinationSlots.All(s => ConflictChecking.AreOverlapping(a, s)));
}
public
override
void
Drop(DragDropState state)
{
state.IsControlPressed =
true
;
var newAppointment = state.DraggedAppointments.OfType<IAppointment>().FirstOrDefault();
if
(newAppointment ==
null
)
return
;
// get the appointments on which the data is dropped
var droppedOnAppointments = state.DestinationAppointmentsSource
.OfType<IAppointment>()
.Where(a => a != newAppointment)
.Where(a => state.DestinationSlots.Any(s => ConflictChecking.AreOverlapping(a, s)))
.ToList();
// the drop did not occur on an appointment
if
(droppedOnAppointments.Count == 0)
return
;
// bad luck: multiple appointments are scheduled at the same time.
// Currently there is no way of telling on which the user dropped the item
if
(droppedOnAppointments.Count > 1)
{
Ambience.Services.Resolve<INotificationService>().NotifyMessage(Resources.Strings.AmbiguousAppointmentsWarningMessage.FormatWith(droppedOnAppointments.Select(a => a.ToString()).Join(Environment.NewLine)));
return
;
}
// custom code: identify the persistent appointment based on custom data and add the person to the appointment
var appointmentId = ((IResource)droppedOnAppointments[0].Resources[1]).ResourceName;
var attendance = ((TaggedResource)newAppointment.Resources[0]).Tag
as
IStudentAttendance;
if
(attendance !=
null
)
SchedulerHelper.AddPersonAppointment(appointmentId, attendance);
// do not call the base so that no appointment is added
//base.Drop(state);
}
}
public
static
class
ConflictChecking
{
public
static
bool
AreOverlapping(IAppointment appointment, Slot slot)
{
// just test that the time interval is intersecting
return
appointment.Start <= slot.End && appointment.End >= slot.Start;
}
}
}
0
Hi Ioan,
I am afraid that currently you cannot get the exact appointment where the dragged appointment is dropped - you can get only the slot as demonstrated in the code library. This feature is already added to our future plans, but at the moment we cannot commit to a specific timeframe for implementing it.
We're sorry for the inconvenience.
Regards,
Yana
the Telerik team
I am afraid that currently you cannot get the exact appointment where the dragged appointment is dropped - you can get only the slot as demonstrated in the code library. This feature is already added to our future plans, but at the moment we cannot commit to a specific timeframe for implementing it.
We're sorry for the inconvenience.
Regards,
Yana
the Telerik team
Explore the entire Telerik portfolio by downloading Telerik DevCraft Ultimate.
0
Accepted
Sandi Markon
Top achievements
Rank 1
answered on 22 Nov 2012, 12:19 PM
My solution was something like this:
The parameter currentScheduleView is the RadScheduleView, which you can obtain, for example, in the override CanStartDrag:
In order to get the currentPoint parameter (that is, the current drag point, relative to the RadScheduleView), you can pick it up in the DragOver event handler. I used:
<!--This way you can get all the appointments, that intersect with the one, you are trying to drop, so all you need to do, is to decide on which appointment you want to drop it (or associate data in the dragged payload with). -->
EDIT: Ignore the above sentence. By using this method you only get the appointment directly under your mouse cursor!! :)
Hope this helps.
IEnumerable<AppointmentItem> items =
VisualTreeHelper.FindElementsInHostCoordinates
(currentPoint,
currentScheduleView)
.OfType<AppointmentItem>();
The parameter currentScheduleView is the RadScheduleView, which you can obtain, for example, in the override CanStartDrag:
public
override
bool
CanStartDrag(DragDropState state)
{
// ...
currentScheduleView = state.ServiceProvider.GetService<IDialogProvider>()
as
RadScheduleView;
// ....
}
In order to get the currentPoint parameter (that is, the current drag point, relative to the RadScheduleView), you can pick it up in the DragOver event handler. I used:
public
ScheduleViewCustomDragDropBehavior()
{
DragDropManager.RemoveDragOverHandler(Application.Current.RootVisual, OnDragOver);
DragDropManager.AddDragOverHandler(Application.Current.RootVisual, OnDragOver,
true
);
}
void
OnDragOver(
object
sender, DragEventArgs e)
{
currentPoint = e.GetPosition(Application.Current.RootVisual);
}
<!--This way you can get all the appointments, that intersect with the one, you are trying to drop, so all you need to do, is to decide on which appointment you want to drop it (or associate data in the dragged payload with). -->
EDIT: Ignore the above sentence. By using this method you only get the appointment directly under your mouse cursor!! :)
Hope this helps.
0
Hi Sandi,
Thank you for sharing your solution.
Kind regards,
Yana
the Telerik team
Thank you for sharing your solution.
Kind regards,
Yana
the Telerik team
Explore the entire Telerik portfolio by downloading Telerik DevCraft Ultimate.
0
Ioan Crisan
Top achievements
Rank 1
answered on 01 Dec 2012, 08:26 AM
Hi Sandi,
thank you for your solution, it worked!
@Yana: I hope Sandi gets some points for the solution.
Best regards,
Ioan
thank you for your solution, it worked!
@Yana: I hope Sandi gets some points for the solution.
Best regards,
Ioan
0
Hello Sandi,
We've updated your points for the involvement.
All the best,
Yana
the Telerik team
We've updated your points for the involvement.
All the best,
Yana
the Telerik team
Explore the entire Telerik portfolio by downloading Telerik DevCraft Ultimate.