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

Appointment stacking Order in TimeLineView

3 Answers 116 Views
Scheduler and Reminder
This is a migrated thread and some comments may be shown as answers.
David
Top achievements
Rank 1
David asked on 17 Nov 2015, 03:46 PM

Hello

Is there a way to keep the vertical stacking order in TimeLineView  GroupedByResource Mode ?

 

I'm working on a planning for different machines and I'm using Hour/30 minutes/15 minutes timescale

I wanted to make WorkTimeException Rules but there's no such things in TimeLineView  so I decided to Create some gray Appointments to show when the machines are not supposed to run.

It's only informative, if the user wants to add or drag-and-drop an appointment that overlaps the grey appointment, he can.

 

The problem is that if the added/Dragged appointment's duration is longer than the gray one, it's stacked above the gray one and I'd like to avoid this.

The Grey appointment must always be on top of the stack (When Refreshing my RadScheduler i'm adding gray appointments first)

 

There's attached picture to illustrate my problem

 

Thanks a lot.

3 Answers, 1 is accepted

Sort by
0
Dess | Tech Support Engineer, Principal
Telerik team
answered on 20 Nov 2015, 11:23 AM
Hello David,

Thank you for writing.

Note that we already have a feature request about adding work time for Timeline view. You can track its progress, subscribe for status changes and add your vote/comment to it on the following link - feedback item.

I would recommend you to indicate the machines non-working not by a separate Appointment, but customize the style for these cells and make them gray. Please refer to the following help article: http://www.telerik.com/help/winforms/scheduler-appearance-formatting-cells.html

Here is a sample code snippet which result is illustrated don the attached screenshot: 
private void radScheduler1_CellFormatting(object sender, Telerik.WinControls.UI.SchedulerCellEventArgs e)
{
    if (e.CellElement.Date.Day == 22&& e.CellElement.Date.Hour>18 &&e.CellElement.Date.Hour<20)
    {
        e.CellElement.DrawFill = true;
        e.CellElement.BackColor = Color.Gray;
        e.CellElement.GradientStyle = Telerik.WinControls.GradientStyles.Solid;
    }
    else
    {
        e.CellElement.ResetValue(LightVisualElement.DrawFillProperty, ValueResetFlags.Local);
        e.CellElement.ResetValue(LightVisualElement.BackColorProperty, ValueResetFlags.Local);
        e.CellElement.ResetValue(LightVisualElement.GradientStyleProperty, ValueResetFlags.Local);
    }
}

I hope this information helps. Should you have further questions I would be glad to help.
 
Regards,
Dess
Telerik
Do you want to have your say when we set our development plans? Do you want to know when a feature you care about is added or when a bug fixed? Explore the Telerik Feedback Portal and vote to affect the priority of the items
0
David
Top achievements
Rank 1
answered on 20 Nov 2015, 11:40 AM

Hi Dess

 

Thank you for your answer, I already Tried to change the cell Color, and it works, but the problem is that the durations must be really accurate, e.g. there's pauses and they are 20 minutes long, Smaller than a cell in Hour/30 minutes timescale and bigger than a 15 minutes timescale and I think it's not possible to colorize only a part of the cell.

 Plus my users needs to freely change the timescale, so having a 20 minutes timescale is not a solution too.

0
Dess | Tech Support Engineer, Principal
Telerik team
answered on 25 Nov 2015, 07:34 AM
Hello David,

Thank you for writing back.

By default, appointments that are placed in the same time cell are sorted considering their duration and start time. That is why longer appointments are rendered above the gray one. You can remove this sorting by creating a custom TimelineAppointmentsPresenter and overriding its ResolveOverlappingAppointments. Afterwards, the presenter should be replaced in the SchedulerElementProvider. Here is a sample code snippet which result is illustrated on the attached gif file: 
public Form1()
{
    InitializeComponent();
 
    this.radScheduler1.ElementProvider = new MyElementProvider(this.radScheduler1);
    this.radScheduler1.ActiveViewType = Telerik.WinControls.UI.SchedulerViewType.Timeline;
    Timescales scale = Timescales.Hours;
    this.radScheduler1.GetTimelineView().ShowTimescale(scale);
 
    Appointment a = new Appointment(DateTime.Today.AddHours(9), TimeSpan.FromMinutes(20), "N/A");
    a.BackgroundId = this.radScheduler1.Backgrounds[2].Id;
    this.radScheduler1.Appointments.Add(a);
 
    Appointment a2 = new Appointment(DateTime.Today.AddHours(9), TimeSpan.FromMinutes(10), "A2");          
    this.radScheduler1.Appointments.Add(a2);
    Appointment a3 = new Appointment(DateTime.Today.AddHours(9), TimeSpan.FromMinutes(40), "A3");
    this.radScheduler1.Appointments.Add(a3);
    Appointment a4 = new Appointment(DateTime.Today.AddHours(9).AddMinutes(1), TimeSpan.FromMinutes(10), "A4");
    this.radScheduler1.Appointments.Add(a4);
    Appointment a5 = new Appointment(DateTime.Today.AddHours(9).AddMinutes(1), TimeSpan.FromMinutes(50), "A5");
    this.radScheduler1.Appointments.Add(a5);
}
 
public class MyElementProvider : SchedulerElementProvider
{
    public MyElementProvider(RadScheduler scheduler) : base(scheduler)
    {
    }
 
    protected override T CreateElement<T>(SchedulerView view, object context)
    {
        if (typeof(T) == typeof(TimelineAppointmentsPresenter))
        {
            return new CustomTimelineAppointmentsPresenter(this.Scheduler, view, (SchedulerTimelineViewElement)context)as T;
        }
        return base.CreateElement<T>(view, context);
    }
}
 
public class CustomTimelineAppointmentsPresenter : TimelineAppointmentsPresenter
{
    public CustomTimelineAppointmentsPresenter(RadScheduler scheduler, SchedulerView view,
        SchedulerTimelineViewElement timelineViewElement) : base(scheduler, view, timelineViewElement)
    {
    }
 
    protected override void ResolveOverlappingAppointments(SizeF availableSize)
    {
        List<AppointmentElement> appointments = new List<AppointmentElement>();
        foreach (AppointmentElement element in this.AppointmentElements)
        {
            if (element.Visibility != ElementVisibility.Collapsed)
            {
                appointments.Add(element);
            }
        }
 
        //do not sort appointments
        //appointments.Sort(new DateTimeComparer(this.Scheduler));
        List<AppointmentElement> arrangedAppointments = new List<AppointmentElement>();
 
        foreach (AppointmentElement appointment in appointments)
        {
            for (int i = 0; i < arrangedAppointments.Count; i++)
            {
                AppointmentElement otherAppointment = arrangedAppointments[i];
 
                if (otherAppointment == appointment)
                {
                    continue;
                }
 
                RectangleF rect = appointment.DesiredBounds;
                rect.Inflate(new SizeF(-2, -2));
                if (otherAppointment.DesiredBounds.IntersectsWith(rect))
                {
                    appointment.DesiredBounds.Y = otherAppointment.DesiredBounds.Bottom;
                    i = -1;
 
                    continue;
                }
            }
 
            arrangedAppointments.Add(appointment);
        }
    }
}

Note that this is just a sample implementation and it may not cover all possible cases. Feel free to modify it in a way which suits your requirement best.

I hope this information helps. If you have any additional questions, please let me know.

Regards,
Dess
Telerik
Do you want to have your say when we set our development plans? Do you want to know when a feature you care about is added or when a bug fixed? Explore the Telerik Feedback Portal and vote to affect the priority of the items
Tags
Scheduler and Reminder
Asked by
David
Top achievements
Rank 1
Answers by
Dess | Tech Support Engineer, Principal
Telerik team
David
Top achievements
Rank 1
Share this question
or