Please refer to the attached gif file illustrating how to reproduce the problem with the Demo application. When you define a new appointment with 24 months interval, it is expected to have this event every 2 years, not each year. To reproduce: you can use the following code snippet as well: MonthlyRecurrenceRule monthlyRecurrenceRule = new MonthlyRecurrenceRule(DateTime.Now, WeekDays.Monday, 2, 24); Appointment a = new Appointment(DateTime.Now, TimeSpan.FromHours(3), "Test"); a.RecurrenceRule = monthlyRecurrenceRule; this.radScheduler1.Appointments.Add(a); Workaround: public Form1() { InitializeComponent(); this.radScheduler1.AppointmentAdded += radScheduler1_AppointmentAdded; } private void radScheduler1_AppointmentAdded(object sender, AppointmentAddedEventArgs e) { MonthlyRecurrenceRule montlyRule = e.Appointment.RecurrenceRule as MonthlyRecurrenceRule; if (montlyRule != null) { CustomMonthlyRecurrenceRule rrule = new CustomMonthlyRecurrenceRule(); rrule.Start = montlyRule.Start; rrule.End = montlyRule.End; rrule.Interval = montlyRule.Interval; rrule.Offset = montlyRule.Offset; rrule.WeekDays = montlyRule.WeekDays; rrule.WeekNumber = montlyRule.WeekNumber; rrule.FirstDayOfWeek = montlyRule.FirstDayOfWeek; rrule.Count = montlyRule.Count; e.Appointment.RecurrenceRule = rrule; } } public class CustomMonthlyRecurrenceRule : MonthlyRecurrenceRule { public override bool MatchAdvancedPattern(DateTime date, DateTimeFormatInfo dateTimeFormat) { int monthIndex = this.Start.Value.Month - date.Month; DateTime calculatedNextDate = this.Start.Value.AddMonths(this.Interval); monthIndex = calculatedNextDate.Month - date.Month; if (calculatedNextDate.Year > date.Year) { return false; } if ((monthIndex % this.Interval) != 0) { return false; } if (0 != this.WeekNumber && !this.MatchWeekOfMonth(date, dateTimeFormat)) { return false; } if (0 != this.DayNumber && !this.MatchDayOfMonth(date, dateTimeFormat)) { return false; } if (this.WeekDays != WeekDays.None && !this.MatchDayOfWeekMask(date, dateTimeFormat.Calendar)) { return false; } if (this.Offset != 0 && !this.MatchOffset(date, dateTimeFormat)) { return false; } return true; } }
Please refer to the attached gif file.
To reproduce: this.radScheduler1.ActiveViewType = Telerik.WinControls.UI.SchedulerViewType.Month; SchedulerMonthView monthView = this.radScheduler1.GetMonthView(); monthView.WeekCount = 5; monthView.EnableCellOverflowButton = false; monthView.EnableAppointmentsScrolling = true; monthView.ShowVerticalNavigator = false; for (int i = 0; i < 5; i++) { this.radScheduler1.Appointments.Add(new Appointment(DateTime.Now, TimeSpan.FromDays(2), "Test" + i)); } for (int i = 5; i < 10; i++) { this.radScheduler1.Appointments.Add(new Appointment(DateTime.Now.AddDays(7), TimeSpan.FromDays(2), "Test" + i)); } for (int i = 10; i < 15; i++) { this.radScheduler1.Appointments.Add(new Appointment(DateTime.Now.AddDays(14), TimeSpan.FromDays(2), "Test" + i)); } this.radScheduler1.Appointments.Add(new Appointment(DateTime.Now.AddMinutes(5),TimeSpan.FromDays(8),"Last")); this.radScheduler1.Appointments.Add(new Appointment(DateTime.Now, TimeSpan.FromDays(14), "A")); this.radScheduler1.Appointments.Add(new Appointment(DateTime.Now.AddDays(7), TimeSpan.FromDays(20), "B")); Workaround: use the cell overflow button: SchedulerMonthView.EnableCellOverflowButton=true.
public Form1() { InitializeComponent(); DateTime d = DateTime.Now.Date; radScheduler1.Appointments.Add(new Appointment(new DateTime(d.Year, d.Month, d.Day, 1, 30, 0), new DateTime(d.Year, d.Month, d.Day, 1, 30, 0), "Appointment_Free_0", "", "")); radScheduler1.Appointments.Add(new Appointment(new DateTime(d.Year, d.Month, d.Day, 8, 30, 0), new DateTime(d.Year, d.Month, d.Day, 9, 0, 0), "Appointment_Free_0", "", "")); radScheduler1.Appointments.Add(new Appointment(new DateTime(d.Year, d.Month, d.Day, 11, 00, 0), new DateTime(d.Year, d.Month, d.Day, 11, 30, 0), "Appointment_Free_0", "", "")); radScheduler1.Appointments.Add(new Appointment(new DateTime(d.Year, d.Month, d.Day, 11, 0, 0), new DateTime(d.Year, d.Month, d.Day, 11, 0, 0), "Appointment_Free_0", "", "")); radScheduler1.Appointments.Add(new Appointment(new DateTime(d.Year, d.Month, d.Day, 10, 30, 0), new DateTime(d.Year, d.Month, d.Day, 11, 0, 0), "Appointment_Free_0", "", "")); radScheduler1.Appointments.Add(new Appointment(new DateTime(d.Year, d.Month, d.Day, 11, 00, 0), new DateTime(d.Year, d.Month, d.Day, 11, 30, 0), "Appointment_Free_0", "", "")); radScheduler1.Appointments.Add(new Appointment(new DateTime(d.Year, d.Month, d.Day, 11, 30, 0), new DateTime(d.Year, d.Month, d.Day, 12, 0, 0), "Appointment_Free_0", "", "")); radScheduler1.Appointments.Add(new Appointment(new DateTime(d.Year, d.Month, d.Day, 14, 0, 0), new DateTime(d.Year, d.Month, d.Day, 14, 30, 0), "Appointment_Free_0", "", "")); radScheduler1.Appointments.Add(new Appointment(new DateTime(d.Year, d.Month, d.Day, 15, 00, 0), new DateTime(d.Year, d.Month, d.Day, 15, 30, 0), "Appointment_Free_0", "", "")); radScheduler1.Appointments.Add(new Appointment(new DateTime(d.Year, d.Month, d.Day, 17, 30, 0), new DateTime(d.Year, d.Month, d.Day, 17, 30, 0), "Appointment_Free_0", "", "")); radScheduler1.ActiveViewType = SchedulerViewType.Day; radScheduler1.EnableExactTimeRendering = true; } Workaround: use a custom DayViewAppointmentsTable this.radScheduler1.ElementProvider = new MyElementProvider(this.radScheduler1); 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(view.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) { } protected override IEnumerable<AppointmentElement> CreateAppointmentElements() { if (this.View != null) { IList<IEvent> appointmentsInView = new List<IEvent>(this.View.Appointments); List<AppointmentElement> elements = DivideAppointmentToElements(appointmentsInView); elements.Sort(0, elements.Count, new DateTimeComparer(this.Scheduler)); foreach (AppointmentElement currentAppointment in elements) { currentAppointment.RelatedAppointments.Clear(); currentAppointment.DesiredBounds = new RectangleF(); } foreach (AppointmentElement appointment in elements) { List<AppointmentElement> intersectingAppointments = this.GetAllAppointmentsInDay(appointment.Start.Day, elements); intersectingAppointments.Remove(appointment); appointment.RelatedAppointments = intersectingAppointments; } return elements; } else { return new List<AppointmentElement>(); } } private List<AppointmentElement> GetAllAppointmentsInDay(int day, List<AppointmentElement> elements) { List<AppointmentElement> result = new List<AppointmentElement>(); foreach (AppointmentElement appointment in elements) { if (appointment.Start.Day == day) { result.Add(appointment); } } return result; } private List<AppointmentElement> DivideAppointmentToElements(IList<IEvent> appointmentsInView) { List<AppointmentElement> childAppointments = new List<AppointmentElement>(); TimeSpan startTime = TimeSpan.FromMinutes(this.GetDayViewBase().RulerStartScale * 60 + this.GetDayViewBase().RulerStartScaleMinutes); TimeSpan endTime = TimeSpan.FromMinutes(this.GetDayViewBase().RulerEndScale * 60 + this.GetDayViewBase().RulerEndScaleMinutes); foreach (IEvent app in appointmentsInView) { SchedulerDayViewBase dayView = this.GetDayViewBase(); bool allDay = (dayView != null) ? dayView.IsAllDayEvent(app) : false; DateTime appStart = this.View.DefaultTimeZone.OffsetTime(app.Start, this.Scheduler.SystemTimeZone); DateTime appEnd = this.View.DefaultTimeZone.OffsetTime(app.End, this.Scheduler.SystemTimeZone); if (!allDay) { // Handle > 1 day appointments if (appStart.Day != appEnd.Day && !(appEnd.Day - appStart.Day == 1 && appEnd.TimeOfDay == TimeSpan.Zero)) { AppointmentElement appointment1 = this.CreateAppointmentElement(this.Scheduler, this.View, app); appointment1.Start = appStart; appointment1.End = DateHelper.GetEndOfDay(appStart); if (appointment1.Start.TimeOfDay >= endTime) { appointment1.Start = new DateTime(appStart.Year, appStart.Month, appStart.Day, 0, 0, 0).Add(endTime).AddMinutes(-(int)this.GetDayViewBase().RangeFactor); } AppointmentElement appointment2 = this.CreateAppointmentElement(this.Scheduler, this.View, app); appointment2.Start = appEnd.Date; appointment2.End = appEnd; if (appointment1.Start >= this.View.StartDate) { childAppointments.Add(appointment1); } if (appointment2.Start >= this.View.StartDate) { childAppointments.Add(appointment2); } } else { AppointmentElement appointment1 = this.CreateAppointmentElement(this.Scheduler, this.View, app); appointment1.Start = appStart; appointment1.End = appEnd; if (appointment1.Start.TimeOfDay < startTime) { appointment1.Start = new DateTime(appStart.Year, appStart.Month, appStart.Day, 0, 0, 0).Add(startTime); } if (appointment1.Start.TimeOfDay >= endTime) { appointment1.Start = new DateTime(appStart.Year, appStart.Month, appStart.Day, 0, 0, 0).Add(endTime).AddMinutes(-(int)this.GetDayViewBase().RangeFactor); } if (appointment1.End.TimeOfDay > endTime) { appointment1.End = new DateTime(appEnd.Year, appEnd.Month, appEnd.Day, 0, 0, 0).Add(endTime); } if (appointment1.End.TimeOfDay <= startTime) { appointment1.End = new DateTime(appEnd.Year, appEnd.Month, appEnd.Day, 0, 0, 0).Add(startTime).AddMinutes((int)this.GetDayViewBase().RangeFactor); } childAppointments.Add(appointment1); } } else if (!dayView.ShowAllDayArea) { DateTimeInterval viewInterval = new DateTimeInterval(this.View.StartDate, DateHelper.GetEndOfDay(this.View.EndDate)); AppointmentElement appointment1 = this.CreateAppointmentElement(this.Scheduler, this.View, app); appointment1.Start = appStart; appointment1.End = DateHelper.GetEndOfDay(appStart); DateTimeInterval interval = new DateTimeInterval(appStart, appointment1.End); if (interval.IntersectsWith(viewInterval)) { if (appointment1.Start.TimeOfDay < startTime) { appointment1.Start = new DateTime(appStart.Year, appStart.Month, appStart.Day, 0, 0, 0).Add(startTime); } if (appointment1.Start.TimeOfDay >= endTime) { appointment1.Start = new DateTime(appStart.Year, appStart.Month, appStart.Day, 0, 0, 0).Add(endTime).AddMinutes(-(int)this.GetDayViewBase().RangeFactor); } if (appointment1.End.TimeOfDay > endTime) { appointment1.End = new DateTime(appEnd.Year, appEnd.Month, appEnd.Day, 0, 0, 0).Add(endTime); } if (appointment1.End.TimeOfDay <= startTime) { appointment1.End = new DateTime(appEnd.Year, appEnd.Month, appEnd.Day, 0, 0, 0).Add(startTime).AddMinutes((int)this.GetDayViewBase().RangeFactor); } childAppointments.Add(appointment1); } DateTime startDate = appStart.AddDays(1).Date; AppointmentElement appointment2 = null; while (startDate <= appEnd.Date.AddDays(-1)) { appointment2 = this.CreateAppointmentElement(this.Scheduler, this.View, app); appointment2.Start = startDate; appointment2.End = DateHelper.GetEndOfDay(startDate); interval = new DateTimeInterval(appointment2.Start, appointment2.End); if (interval.IntersectsWith(viewInterval)) { childAppointments.Add(appointment2); } startDate = startDate.AddDays(1); } DateTime endDate = appEnd.Date; DateTime endAppointmentDate = appEnd; appointment2 = this.CreateAppointmentElement(this.Scheduler, this.View, app); appointment2.Start = endDate; appointment2.End = endAppointmentDate; interval = new DateTimeInterval(endDate, endAppointmentDate); if (interval.IntersectsWith(viewInterval) && interval.Start != appStart) { childAppointments.Add(appointment2); } } } return childAppointments; } private AppointmentElement CreateAppointmentElement(RadScheduler scheduler, SchedulerView view, IEvent appointment) { AppointmentElement appointmentElement = null; if (scheduler.AppointmentElementFactory != null) { appointmentElement = scheduler.AppointmentElementFactory.CreateAppointmentElement(scheduler, view, appointment); } else { appointmentElement = scheduler.ElementProvider.GetElement<AppointmentElement>(view, appointment); } return appointmentElement; } }
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.
To reproduce: follow the steps from the attached gif file. Workaround: public Form1() { InitializeComponent(); this.radScheduler1.RecurrenceEditDialogShowing += radScheduler1_RecurrenceEditDialogShowing; } CustomEditRecurrenceDialog dialog = null; private void radScheduler1_RecurrenceEditDialogShowing(object sender, Telerik.WinControls.UI.RecurrenceEditDialogShowingEventArgs e) { if (dialog == null) { dialog = new CustomEditRecurrenceDialog(e.Appointment); } e.RecurrenceEditDialog = dialog; } public class CustomEditRecurrenceDialog : EditRecurrenceDialog { public CustomEditRecurrenceDialog(IEvent appointment) : base(appointment) { } protected override void ApplyAppointmentDates() { DateTime end = this.appointment.End; base.ApplyAppointmentDates(); this.appointment.End = new DateTime(end.Year, end.Month, end.Day, this.timeEnd.Value.Hour, this.timeEnd.Value.Minute, this.timeEnd.Value.Second); } }
Workaround: use your own icon: public Form1() { InitializeComponent(); this.radScheduler1.RecurrenceEditDialogShowing+=radScheduler1_RecurrenceEditDialogShowing; } private void radScheduler1_RecurrenceEditDialogShowing(object sender, Telerik.WinControls.UI.RecurrenceEditDialogShowingEventArgs e) { ((RadForm)e.RecurrenceEditDialog).Icon = Properties.Resources.WinFormsIcon; }
Please refer to the attached screenshots. A sample project is attached. There is a known issue in the .NET Framework considering the "fa-IR" culture. Please refer to the following MSDN resource for a solution which is included in the sample project: https://code.msdn.microsoft.com/Fixing-Persian-Locale-for-6e66e044#content Workaround: private void radScheduler1_CellFormatting(object sender, SchedulerCellEventArgs e) { MonthCellElement monthCellElement = e.CellElement as MonthCellElement; if (monthCellElement != null) { monthCellElement.Header.Text = monthCellElement.Date.ToString("dd", this.radScheduler1.Culture); } }
To reproduce: please refer to the attached gif file Dim a1 As New Appointment(DateTime.Today.AddDays(-1), TimeSpan.FromDays(3), "Termin1") a1.AllDay = True Dim a2 As New Appointment(DateTime.Today.AddDays(-1), TimeSpan.FromDays(1), "Termin2") a2.AllDay = True Me.RadScheduler1.Appointments.Add(a1) Me.RadScheduler1.Appointments.Add(a2) Workaround: specify precisely the end date including the time part as well Dim a1 As New Appointment(DateTime.Today.AddDays(-1), TimeSpan.FromDays(3).Add(TimeSpan.FromMinutes(1)), "Termin1") a1.AllDay = False Dim a2 As New Appointment(DateTime.Today.AddDays(-1), TimeSpan.FromDays(2).Add(TimeSpan.FromMinutes(1)), "Termin2") a2.AllDay = False Me.RadScheduler1.Appointments.Add(a1) Me.RadScheduler1.Appointments.Add(a2)
To reproduce: public Form1() { InitializeComponent(); this.radScheduler1.ActiveViewType = Telerik.WinControls.UI.SchedulerViewType.Timeline; this.radScheduler1.EnableGesture(Telerik.WinControls.GestureType.Pan); this.radScheduler1.DisableGesture(Telerik.WinControls.GestureType.Zoom); this.radScheduler1.ZoomGesture+=radScheduler1_ZoomGesture; this.radScheduler1.PanGesture+=radScheduler1_PanGesture; } private void radScheduler1_PanGesture(object sender, Telerik.WinControls.PanGestureEventArgs e) { Console.WriteLine("Pan should fire"); } private void radScheduler1_ZoomGesture(object sender, Telerik.WinControls.ZoomGestureEventArgs e) { Console.WriteLine("Zoom should NOT fire"); } Workaround: public class CustomScheduler : RadScheduler { public override string ThemeClassName { get { return typeof(RadScheduler).FullName; } } protected override void OnZoomGesture(Telerik.WinControls.ZoomGestureEventArgs args) { //stop the basic logic //base.OnZoomGesture(args); } }
Please refer to the attached file. Workaround: clear remind objects when the appointment is changed: private void radScheduler1_AppointmentChanged(object sender, AppointmentChangedEventArgs e) { schedulerReminder.ClearRemindObjects(); foreach (Appointment a in this.radScheduler1.Appointments) { schedulerReminder.AddRemindObject(a); } }
Workaround: public class MyTimelineGroupingByResourcesElement : TimelineGroupingByResourcesElement { public MyTimelineGroupingByResourcesElement(RadScheduler scheduler, SchedulerView view) : base(scheduler, view) { } public override void NavigateForward() { TimeSpan ts = (this.View as SchedulerTimelineView).RangeEndDate - this.View.StartDate; int differenceInDays = ts.Days; int displayedCells = (this.View as SchedulerTimelineView).GetScaling().DisplayedCellsCount; if (differenceInDays >= displayedCells) { base.NavigateForward(); } } } public class MyElementProvider : SchedulerElementProvider { public MyElementProvider(RadScheduler scheduler) : base(scheduler) { } protected override T CreateElement<T>(SchedulerView view, object context) { if (typeof(T) == typeof(TimelineGroupingByResourcesElement)) { return new MyTimelineGroupingByResourcesElement(this.Scheduler, view) as T; } return base.CreateElement<T>(view, context); } } public RadForm2() { InitializeComponent(); this.radScheduler1.ElementProvider = new MyElementProvider(this.radScheduler2); }
To reproduce: use the following code snippet: private BindingList<MyEvent> eventsSource = new BindingList<MyEvent>(); private AppointmentMappingInfo appointmentMappingInfo_g = new AppointmentMappingInfo(); public RadForm2() { InitializeComponent(); } private void RadForm2_Load(object sender, EventArgs e) { radScheduler1.ActiveViewType = radScheduler2.ActiveViewType = SchedulerViewType.Timeline; radScheduler1.GetTimelineView().ShowTimescale(Timescales.Days); radScheduler2.GetTimelineView().ShowTimescale(Timescales.Days); radScheduler1.GetTimelineView().RangeStartDate = radScheduler2.GetTimelineView().RangeStartDate = new DateTime(2015, 9, 1); radScheduler1.GetTimelineView().RangeEndDate = radScheduler2.GetTimelineView().RangeEndDate = new DateTime(2015, 9, 30); radScheduler1.GetTimelineView().StartDate = radScheduler2.GetTimelineView().StartDate = new DateTime(2015, 9, 1); radScheduler1.GetTimelineView().GetScaling().DisplayedCellsCount = radScheduler2.GetTimelineView().GetScaling().DisplayedCellsCount = 7; appointmentMappingInfo_g.Start = "Start"; appointmentMappingInfo_g.End = "End"; appointmentMappingInfo_g.Summary = "Subject"; appointmentMappingInfo_g.Description = "Description"; appointmentMappingInfo_g.Location = "Location"; appointmentMappingInfo_g.UniqueId = "Id"; SchedulerBindingDataSource dataSource_l = new SchedulerBindingDataSource(); dataSource_l.EventProvider.Mapping = appointmentMappingInfo_g; dataSource_l.EventProvider.DataSource = eventsSource; radScheduler2.DataSource = dataSource_l; FillAppointments(); } private void FillAppointments() { Appointment appointment = new Appointment(new DateTime(2015, 9, 2), new DateTime(2015, 9, 6), "DU 2 AU 6"); appointment.AllDay = true; radScheduler1.Appointments.BeginUpdate(); radScheduler1.Appointments.Add(appointment); radScheduler1.Appointments.EndUpdate(); MyEvent appointment2 = new MyEvent(new DateTime(2015, 9, 2), new DateTime(2015, 9, 6), "DU 2 AU 6","","",""); radScheduler2.Appointments.BeginUpdate(); eventsSource.Add(appointment2); radScheduler2.Appointments.EndUpdate(); } public class MyEvent { public DateTime Start { get; set; } public DateTime End { get; set; } public string Subject { get; set; } public string Description { get; set; } public string Location { get; set; } public string UniqueId { get; set; } public MyEvent(DateTime start, DateTime end, string subject, string description, string location, string uniqueId) { this.Start = start; this.End = end; this.Subject = subject; this.Description = description; this.Location = location; this.UniqueId = uniqueId; } } Workaround: specify the end day with 1 second more: MyEvent appointment2 = new MyEvent(new DateTime(2015, 9, 2), new DateTime(2015, 9, 6, 0, 0, 1), "DU 2 AU 6", "", "", "");
To reproduce: use a German TimeZone 1. Create a recurring appointment with a yearly recurrence rule on the last Sunday of October. 2. Export to iCal. As a result, the TimeZone information is not correct. The exported RRULE BYSETPOS=5 defines the 5th Sunday. This is wrong. There may be a year with 5 Sundays in March/October but that is not true for every year. The correct encoding for ics files is BYSETPOS=-1. This indicates the last Sunday of a month. The other error is the DTSTART:16010101T030000 and DTSTART:00010101T020000. The German daylight rule is valid since 1996, not since 1601 or year 1. Note: German timezone defines the switch to daylight saving time as - start on last Sunday in March at 03:00 - end on last Sunday in October at 02:00 This rule is valid since 1996. Alert: Events created in RadScheduler for the last Sunday of a month are correct! The rule here is exported as expected and contains BYSETPOS=-1:
To reproduce: public Form1() { InitializeComponent(); this.radScheduler1.ActiveViewType = SchedulerViewType.Timeline; Timescales scale = Timescales.Hours; this.radScheduler1.GetTimelineView().ShowTimescale(scale); Appointment app1 = new Appointment(DateTime.Today.AddHours(6), TimeSpan.FromMinutes(25), "A1"); Appointment app2 = new Appointment(DateTime.Today.AddHours(6).AddMinutes(25), TimeSpan.FromMinutes(16), "A2"); Appointment app3 = new Appointment(DateTime.Today.AddHours(6).AddMinutes(41), TimeSpan.FromMinutes(12), "A3"); this.radScheduler1.Appointments.Add(app1); this.radScheduler1.Appointments.Add(app2); this.radScheduler1.Appointments.Add(app3); this.radScheduler1.EnableExactTimeRendering = true; } Workaround: this.radScheduler1.ElementProvider = new MyElementProvider(this.radScheduler1); 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); } } 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); } } }
Workaround: private void radScheduler1_CellFormatting(object sender, Telerik.WinControls.UI.SchedulerCellEventArgs e) { if (e.CellElement is SchedulerHeaderCellElement && e.CellElement.Text == "Local") { e.CellElement.TextAlignment = ContentAlignment.BottomLeft; } }
To reproduce: 1. Add a RadDock with one DocumentWindow. 2. Place a RadSchedulerNavigator in the DocumentWindow. 3. Add a RadButton and use the following code snippet: private void radButton1_Click(object sender, EventArgs e) { this.radSchedulerNavigator1.SchedulerNavigatorElement.TimeZonesDropDown.SelectedIndexChanging += TimeZonesDropDown_SelectedIndexChanging; string path = @"..\..\layout.xml"; this.radDock1.SaveToXml(path); this.radDock1.LoadFromXml(path); RadScheduler sched = new RadScheduler(); this.documentWindow1.Controls.Add(sched); sched.Dock = DockStyle.Left; this.radSchedulerNavigator1.AssociatedScheduler = this.documentWindow1.Controls[1] as RadScheduler; } After running the application and clicking the button, you will notice that RadScheduler has time zone "Casablanca" but the RadSchedulerNavigator has a different time zone. Workaround: associate the RadSchedulerNavigator before loading the layout.