Unplanned
Last Updated: 16 Aug 2017 07:57 by ADMIN
Currently, only one resource can be printed on a single page. It should be possible to print the appointments for more than one resource on a single page, just like RadScheduler allows you to set the number of resources per view.
Unplanned
Last Updated: 15 Aug 2017 10:08 by ADMIN
ADMIN
Created by: Dess | Tech Support Engineer, Principal
Comments: 0
Category: Scheduler/Reminder
Type: Feature Request
1
In Outlook, when the appontment height should be smaller than the height needed to accommodate 1 line of text, the appointment status size is being changed instead.
Unplanned
Last Updated: 15 Aug 2017 10:02 by ADMIN
ADMIN
Created by: Dess | Tech Support Engineer, Principal
Comments: 0
Category: Scheduler/Reminder
Type: Feature Request
5

			
Unplanned
Last Updated: 15 Aug 2017 10:02 by ADMIN
ADMIN
Created by: Dess | Tech Support Engineer, Principal
Comments: 0
Category: Scheduler/Reminder
Type: Feature Request
3
It would be nice if the RadScheduler allows dragging of multiple selected appointments and change the events'  start time in correspondence with the active appointment offset time.
Unplanned
Last Updated: 15 Aug 2017 10:02 by ADMIN
ADD. RadScheduler - add the ability to change  the culture of the generated print document.
Unplanned
Last Updated: 15 Aug 2017 10:02 by ADMIN
ADMIN
Created by: Dess | Tech Support Engineer, Principal
Comments: 0
Category: Scheduler/Reminder
Type: Feature Request
4

			
Unplanned
Last Updated: 15 Aug 2017 09:45 by ADMIN
ADMIN
Created by: Dess | Tech Support Engineer, Principal
Comments: 0
Category: Scheduler/Reminder
Type: Feature Request
0
Implement similar functionality as the exact time rendering in Outlook (DayView) using the status area. Please refer to the attached screenshot.
Unplanned
Last Updated: 15 Aug 2017 09:45 by ADMIN
ADMIN
Created by: Stefan
Comments: 2
Category: Scheduler/Reminder
Type: Feature Request
1

			
Unplanned
Last Updated: 15 Aug 2017 09:38 by ADMIN
ADMIN
Created by: Paul
Comments: 0
Category: Scheduler/Reminder
Type: Feature Request
1
When in multi day view if many days are being added, each day visual becomes so narrow that the application practically becomes useless. If there is horizontal scroll bar the view could be stretched and the user would be able to scroll between the days.
Unplanned
Last Updated: 15 Aug 2017 09:38 by ADMIN
ADMIN
Created by: Jack
Comments: 0
Category: Scheduler/Reminder
Type: Feature Request
2
Currently RadScheduler does not support binding to DataView objects.
Unplanned
Last Updated: 15 Aug 2017 09:33 by ADMIN
The functionality provided by the EditRecurrenceDialog should also be available in a user control. This would allow the users to embed it in their applications.
Unplanned
Last Updated: 15 Aug 2017 09:33 by Jesse Dyck
It should be possible to set the step of the ruler in Day/Week view to two or more hours.
Unplanned
Last Updated: 15 Aug 2017 09:23 by ADMIN
ADMIN
Created by: Ivan Todorov
Comments: 0
Category: Scheduler/Reminder
Type: Feature Request
2
Add the possibility to have multiple time intervals on the DayView's display range.
Unplanned
Last Updated: 15 Aug 2017 09:23 by ADMIN
ADMIN
Created by: Dobry Zranchev
Comments: 0
Category: Scheduler/Reminder
Type: Feature Request
2
Filtering should not show the appointments which have their resources not visible.
Unplanned
Last Updated: 14 Aug 2017 12:00 by ADMIN
Please refer to the attached sample project and screenshot. Note that if RadScheduler is not grouped by resources, the scrollbar works as expected.
Unplanned
Last Updated: 14 Aug 2017 11:55 by ADMIN
ADMIN
Created by: Dess | Tech Support Engineer, Principal
Comments: 0
Category: Scheduler/Reminder
Type: Bug Report
1
Please refer to the attached sample project. When you toggle the button the Visible property for the first resource is inverted. However, it doesn't take effect in RadScheduler and the resource is always visible.

Workaround: Currently, if you want to hide some of the resources, you should remove them from the Resources collection of RadScheduler. When you want to use them again, you should just add them to the same collection.
Unplanned
Last Updated: 14 Aug 2017 11:54 by ADMIN
ADMIN
Created by: Dess | Tech Support Engineer, Principal
Comments: 0
Category: Scheduler/Reminder
Type: Bug Report
1
To reproduce: Use the following code snippet:

            DateTime dt = DateTime.Now;
            this.radScheduler1.Appointments.Add(new Appointment(dt, TimeSpan.FromHours(4),"A1"));
            this.radScheduler1.Appointments.Add(new Appointment(dt, TimeSpan.FromHours(4),"A2"));

By default, when two appointments start at the same time, on the left side it is displayed the shorter appointment. Hence, if you start resizing an appointment it may jump to another location leaving the mouse in a  wrong and inconsistent position.  The attached gif illustartes the behavior.

Workaround: 

public RadForm1()
{
    InitializeComponent();

    this.radScheduler1.ElementProvider = new MyElementProvider(this.radScheduler1);

    DateTime dt = DateTime.Now;
    this.radScheduler1.Appointments.Add(new Appointment(dt, TimeSpan.FromHours(4),"A1"));
    this.radScheduler1.Appointments.Add(new Appointment(dt, TimeSpan.FromHours(4),"A2"));
}

private class AppointmentDateInfo : IComparable
{
    public AppointmentElement appointment;
    public DateTime date;
    public bool isEnd;
    private DateTimeComparer comparer;

    public AppointmentDateInfo(AppointmentElement appointment, DateTime date, bool isEnd)
    {
        this.comparer = new DateTimeComparer(appointment.Scheduler);
        this.appointment = appointment;
        this.date = date;
        this.isEnd = isEnd;
    }

    public int CompareTo(object obj)
    {
        AppointmentDateInfo other = obj as AppointmentDateInfo;
        if (other == null)
        {
            return 1;
        }

        int res = date.CompareTo(other.date);
        if (res == 0)
        {
            if (other.appointment != this.appointment)
            {
                res = other.isEnd.CompareTo(isEnd);
            }
            else
            {
                res = this.isEnd.CompareTo(other.isEnd);
            }
        }
        if (appointment.Start.Equals(other.appointment.Start))
        {
            return res != 0 ? res : appointment.AppointmentSubject.CompareTo(other.appointment.AppointmentSubject);
        }
        return res != 0 ? res : comparer.Compare(appointment, other.appointment);
    }
}

public class MyElementProvider : SchedulerElementProvider
{
    public MyElementProvider(RadScheduler scheduler) : base(scheduler)
    {
    }

    protected override T CreateElement<T>(SchedulerView view, object context)
    {
        if (typeof(T) == typeof(DayViewAppointmentsTable))
        {
            return new CustomDayViewAppointmentsTable(this.Scheduler, view, (DayViewAppointmentsArea)context)as T;
        }
        
        return base.CreateElement<T>(view, context);
    }
}

public class CustomDayViewAppointmentsTable : DayViewAppointmentsTable
{
    public CustomDayViewAppointmentsTable(RadScheduler scheduler, SchedulerView view, DayViewAppointmentsArea area) : base(scheduler, view, area)
    {
    }

    private int FindLaneSpan(AppointmentElement appointment, Dictionary<AppointmentElement, int> appointmentLanes, int maxLanes)
    {
        int lane = appointmentLanes[appointment];
        int span = maxLanes - lane;

        int cellsPerHour = this.GetDayViewBase().GetNumberOfCellsPerHour();
        int minutesPerSlot = 60 / cellsPerHour;

        DateTime roundedAppStart = this.GetRulerRoundedDateTime(appointment.Start, false);
        DateTime roundedAppEnd = this.GetRulerRoundedDateTime(appointment.End, true);

        if (appointment.Start == appointment.End)
        {
            roundedAppEnd = roundedAppEnd.AddMinutes(minutesPerSlot);
        }

        foreach (KeyValuePair<AppointmentElement, int> item in appointmentLanes)
        {
            if (appointment == item.Key)
            {
                continue;
            }

            DateTime roundedItemStart = this.GetRulerRoundedDateTime(item.Key.Start, false);
            DateTime roundedItemEnd = this.GetRulerRoundedDateTime(item.Key.End, true);

            if (item.Key.Start == item.Key.End)
            {
                roundedItemEnd = roundedItemEnd.AddMinutes(minutesPerSlot);
            }

            if (roundedItemStart < roundedAppEnd && roundedItemEnd > roundedAppStart && item.Value > lane)
            {
                span = Math.Min(span, item.Value - lane);
            }
        }

        return span;
    }

    private int FindFreeLane(List<AppointmentElement> overlappingAppointments, Dictionary<AppointmentElement, int> appointmentLanes)
    {
        List<int> indexes = new List<int>();

        for (int i = 0; i < overlappingAppointments.Count; i++)
        {
            indexes.Add(appointmentLanes[overlappingAppointments[i]]);
        }

        indexes.Sort();

        for (int i = 0; i < indexes.Count; i++)
        {
            if (i < indexes[i])
            {
                return i;
            }
        }

        return overlappingAppointments.Count;
    }
    
    protected override void ArrangeAppointments(SizeF finalSize)
    {
        RectangleF containerRect = new RectangleF(PointF.Empty, finalSize);
        List<AppointmentElement> appointmentsInLayout = new List<AppointmentElement>();

        foreach (AppointmentElement element in this.AppointmentElements)
        {
            if (element.Visibility != ElementVisibility.Collapsed)
            {
                appointmentsInLayout.Add(element);
            }
        }

        appointmentsInLayout.Sort(new DateTimeComparer(this.Scheduler));
        Dictionary<AppointmentElement, object> arrangedAppointments = new Dictionary<AppointmentElement, object>();

        foreach (AppointmentElement appointmentElement in appointmentsInLayout)
        {
            if (arrangedAppointments.ContainsKey(appointmentElement))
            {
                continue;
            }

            appointmentElement.RelatedAppointments.Sort(new DateTimeComparer(this.Scheduler));

            List<AppointmentDateInfo> appointmentDates = new List<AppointmentDateInfo>();
            List<AppointmentElement> overlappingAppointments = new List<AppointmentElement>();
            Dictionary<AppointmentElement, int> appointmentLanes = new Dictionary<AppointmentElement, int>();

            foreach (AppointmentElement relatedAppointment in appointmentElement.RelatedAppointments)
            {
                if (relatedAppointment.Visibility == ElementVisibility.Collapsed)
                {
                    continue;
                }

                DateTime appStart = relatedAppointment.Start <= relatedAppointment.End ? relatedAppointment.Start : relatedAppointment.End;
                DateTime appEnd = relatedAppointment.Start <= relatedAppointment.End ? relatedAppointment.End : relatedAppointment.Start;

                if (!this.Scheduler.EnableExactTimeRendering)
                {
                    if (appStart != appEnd)
                    {
                        appointmentDates.Add(new AppointmentDateInfo(relatedAppointment, this.GetRulerRoundedDateTime(appStart, false), false));
                        appointmentDates.Add(new AppointmentDateInfo(relatedAppointment, this.GetRulerRoundedDateTime(appEnd, true), true));
                    }
                    else
                    {
                        int cellsPerHour = this.GetDayViewBase().GetNumberOfCellsPerHour();
                        int minutesPerSlot = 60 / cellsPerHour;

                        appointmentDates.Add(new AppointmentDateInfo(relatedAppointment, this.GetRulerRoundedDateTime(appStart, false), false));
                        appointmentDates.Add(new AppointmentDateInfo(relatedAppointment, this.GetRulerRoundedDateTime(appEnd, true).AddMinutes(minutesPerSlot),
                            true));
                    }
                }
                else
                {
                    appointmentDates.Add(new AppointmentDateInfo(relatedAppointment, appStart, false));
                    appointmentDates.Add(new AppointmentDateInfo(relatedAppointment, appEnd, true));
                }
            }

            appointmentDates.Sort();
            int maxLanesCount = 0;

            for (int i = 0; i < appointmentDates.Count; i++)
            {
                if (!appointmentDates[i].isEnd)
                {
                    int freeLane = FindFreeLane(overlappingAppointments, appointmentLanes);
                    appointmentLanes.Add(appointmentDates[i].appointment, freeLane);
                    overlappingAppointments.Add(appointmentDates[i].appointment);
                    maxLanesCount = Math.Max(maxLanesCount, freeLane + 1);
                }
                else
                {
                    overlappingAppointments.Remove(appointmentDates[i].appointment);
                }

                if (overlappingAppointments.Count == 0)
                {
                    foreach (KeyValuePair<AppointmentElement, int> item in appointmentLanes)
                    {
                        AppointmentElement appointment = item.Key;
                        int lane = item.Value;
                        DateTime rulerRoundStart = this.GetRulerRoundedDateTime(appointment.Start, false);
                        DateTime rulerRoundEnd = this.GetRulerRoundedDateTime(appointment.End, true);

                        if (appointment.Start == appointment.End)
                        {
                            int cellsPerHour = this.GetDayViewBase().GetNumberOfCellsPerHour();
                            int minutesPerSlot = 60 / cellsPerHour;

                            rulerRoundEnd = rulerRoundEnd.AddMinutes(minutesPerSlot);
                        }

                        PointF location = GetItemLocationInTable(appointment.Start, finalSize);

                        float dayWidth = this.Area.DayViewElement.GetColumnWidth(this.Area.DayViewElement.GetColumnForDate(rulerRoundStart), finalSize.Width);
                        int laneSpan = FindLaneSpan(appointment, appointmentLanes, maxLanesCount);

                        SizeF size = new SizeF(dayWidth / maxLanesCount * laneSpan, this.GetItemHeight(appointment.Start, appointment.End));
                        location.X += dayWidth / maxLanesCount * lane + this.Area.DayViewElement.AppointmentMargin.Left;
                        location.Y += this.Area.DayViewElement.AppointmentMargin.Top;
                        size.Width -= this.Area.DayViewElement.AppointmentMargin.Horizontal;

                        appointment.DesiredBounds = this.OnAppointmentLayout(appointment, new RectangleF(location, size), finalSize);
                        if (!arrangedAppointments.ContainsKey(appointment))
                        {
                            arrangedAppointments.Add(appointment, null);
                        }
                    }

                    appointmentLanes.Clear();
                    maxLanesCount = 0;
                }
            }

            for (int i = 0; i < appointmentsInLayout.Count; i++)
            {
                AppointmentElement appointment = appointmentsInLayout[i];

                if (appointment.Visibility != ElementVisibility.Visible)
                    continue;

                RectangleF rectangle = appointment.DesiredBounds;

                if (this.RightToLeft)
                {
                    rectangle = LayoutUtils.RTLTranslateNonRelative(rectangle, containerRect);
                }

                appointment.Arrange(rectangle);
            }
        }
    }
}

Unplanned
Last Updated: 14 Aug 2017 11:52 by ADMIN
To reproduce: please refer to the attached sample project and run it. Try to edit the existing appointment by using the inline editor. As a result, the AppointmentAdded event will be fired. You will notice that the Appointments collection contains more appointments than the existing ones. Note that if you use the edit dialog, this event is not fired and the behavior is as expected.

Workaround: RadScheduler1.SchedulerElement.EditorManager.EditorViewMode = SchedulerEditorViewMode.EditorDialog
Unplanned
Last Updated: 14 Aug 2017 11:03 by ADMIN
Currently the range starts from the start date of the first appointment an ends with the end date of the last appointment within the range. One should be able to show that there are no appointments within the specified range (start from the DateStartRange).