To reproduce: Appointment a1 = new Appointment(DateTime.Today.AddHours(10).AddMinutes(30), TimeSpan.FromMinutes(30), "A1"); Appointment a2 = new Appointment(DateTime.Today.AddHours(11) , TimeSpan.FromMinutes(30), "A2"); Appointment a3 = new Appointment(DateTime.Today.AddHours(11).AddMinutes(30), TimeSpan.FromMinutes(30), "A3"); this.radScheduler1.Appointments.Add(a1); this.radScheduler1.Appointments.Add(a2); this.radScheduler1.Appointments.Add(a3); this.radScheduler1.ActiveViewType = SchedulerViewType.Timeline; SchedulerTimelineView timelineView = radScheduler1.GetTimelineView(); timelineView.ShowTimescale(Timescales.Minutes); timelineView.GetScaling().DisplayedCellsCount = 10; Please refer to the attached sample project which incorrect behavior when scrolling is illustrated in the attached gif file. Workaround: instead of specifying 30 minutes duration of an appointment, use 29 minutes and 59 seconds.
Workaround: create a derivative of the EditAppointmentDialog. Open the designer and adjust the form's height and button's position. Then replace the default dialog with the custom one: public RadForm1() { InitializeComponent(); this.radScheduler1.AppointmentEditDialogShowing += radScheduler1_AppointmentEditDialogShowing; } CustomEditAppointmentDialog dialog; private void radScheduler1_AppointmentEditDialogShowing(object sender, Telerik.WinControls.UI.AppointmentEditDialogShowingEventArgs e) { if (dialog==null) { dialog = new CustomEditAppointmentDialog(); } e.AppointmentEditDialog = dialog; }
The resulting behavior should be similar to having all day appointments in the control with the view having its ShowAllDayArea property set to false. Currently when printed the all day appointments are drawn in the all day area.
Please refer to the attached gif files. The separator ";" should be displayed when the appointment's information is displayed in a single line. Otherwise, the information should be displayed multi-line like in the OutlookSeparator.gif. Note: you can test with different AppointmentTitleFormat. Important: setting the Text in the AppointmentFormatting event must have higher priority than AppointmentTitleFormat!!! Workaround: Sub New() InitializeComponent() Me.RadScheduler1.ElementProvider = New MyElementProvider(Me.RadScheduler1) Me.RadScheduler1.Appointments.Add(New Appointment(DateTime.Now, TimeSpan.FromMinutes(40), "Summary", "Description", "Location")) End Sub Public Class CustomAppointmentElement Inherits AppointmentElement Public Sub New(scheduler As RadScheduler, view As SchedulerView, appointment As IEvent) MyBase.New(scheduler, view, appointment) End Sub Protected Overrides Function CreateAppointmentText() As String Return String.Format("{0:HH:mm} - {1:HH:mm} {3} <b>{2}</b>", Me.Appointment.Start, Me.Appointment.End, _ Me.Appointment.Location, Me.Appointment.Summary) End Function End Class Public Class MyElementProvider Inherits SchedulerElementProvider Public Sub New(scheduler As RadScheduler) MyBase.New(scheduler) End Sub Protected Overrides Function CreateElement(Of T As SchedulerVisualElement)(view As SchedulerView, context As Object) As T If GetType(T) = GetType(AppointmentElement) Then Return TryCast(New CustomAppointmentElement(Me.Scheduler, view, DirectCast(context, IEvent)), T) End If Return MyBase.CreateElement(Of T)(view, context) End Function End Class
To reproduce: use the following code Sub New() InitializeComponent() AddHandler Me.RadScheduler1.ActiveViewChanged, AddressOf ActiveViewChanged Me.RadScheduler1.ActiveViewType = Telerik.WinControls.UI.SchedulerViewType.Week End Sub Private Sub ActiveViewChanged(sender As Object, e As Telerik.WinControls.UI.SchedulerViewChangedEventArgs) Dim dayView As SchedulerDayViewBase = TryCast(Me.RadScheduler1.ActiveView, SchedulerDayViewBase) Dim dayViewElement As SchedulerDayViewElement = TryCast(Me.RadScheduler1.SchedulerElement.ViewElement, SchedulerDayViewElement) If dayViewElement IsNot Nothing Then Dim ruler As RulerPrimitive = dayViewElement.DataAreaElement.Ruler ruler.StartScale = 6 ruler.EndScale = 22 dayView.WorkTime = New TimeInterval(TimeSpan.FromHours(13), TimeSpan.FromHours(16)) End If End Sub When you run the project you will notice that the work time starts from 19:00 to 22:00. When you switch between DayView and WeekView, the ruler is not aligned with the scheduler cells as well. The attached gif file illustrates the incorrect behavior. Workaround: use the RulerStartScale and RulerEndScale of the SchedulerDayViewBase Sub New() InitializeComponent() AddHandler Me.RadScheduler1.ActiveViewChanged, AddressOf ActiveViewChanged Me.RadScheduler1.ActiveViewType = Telerik.WinControls.UI.SchedulerViewType.Week End Sub Private Sub ActiveViewChanged(sender As Object, e As Telerik.WinControls.UI.SchedulerViewChangedEventArgs) Dim dayView As SchedulerDayViewBase = TryCast(Me.RadScheduler1.ActiveView, SchedulerDayViewBase) If dayView IsNot Nothing Then dayView.RulerStartScale = 6 dayView.RulerEndScale = 22 dayView.WorkTime = New TimeInterval(TimeSpan.FromHours(13), TimeSpan.FromHours(16)) End If End Sub
To reproduce: public Form1() { InitializeComponent(); this.radScheduler1.ActiveViewType = SchedulerViewType.Week; SchedulerWeekView weekView = this.radScheduler1.GetWeekView(); weekView.RangeFactor = ScaleRange.QuarterHour; Appointment appointment = new Appointment(DateTime.Today.AddHours(23).AddMinutes(45), new TimeSpan(0,15,0), "Meeting"); DailyRecurrenceRule rrule = new DailyRecurrenceRule(appointment.Start, 1, 10); appointment.RecurrenceRule = rrule; this.radScheduler1.Appointments.Add(appointment); } Workaround: In order to deal with the border case with appointment ending at 00:00h, use a new TimeSpan(0,14,59)
To reproduce: this.radScheduler1.ActiveViewType = SchedulerViewType.Month; for (int i = 0; i < 10; i++) { this.radScheduler1.Appointments.Add(new Appointment(DateTime.Now.AddHours(i),TimeSpan.FromMinutes(30),"A"+i)); } Scroll to the bottom and try to select an appointment. You will notice that selection is not possible. The attached gif file illustrates the incorrect behavior. Workaround: use the overflow button by setting the SchedulerMonthView.EnableCellOverflowButton property to true: SchedulerMonthView monthView = this.radScheduler1.GetMonthView(); monthView.EnableCellOverflowButton = true;
Please refer to the attached screenshot. Workaround: public Form1() { InitializeComponent(); 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(AppointmentElement)) { return new CustomAppointmentElement(this.Scheduler, view, (IEvent)context)as T; } return base.CreateElement<T>(view, context); } } public class CustomAppointmentElement : AppointmentElement { protected override Type ThemeEffectiveType { get { return typeof(AppointmentElement); } } public CustomAppointmentElement(RadScheduler scheduler, SchedulerView view, IEvent appointment) : base(scheduler, view, appointment) { } protected override SizeF ArrangeOverride(SizeF finalSize) { SizeF s = base.ArrangeOverride(finalSize); return new SizeF(s.Width - 5,s.Height); } }
To reproduce: Public Class Form1 Sub New() InitializeComponent() Me.RadScheduler1.EnableExactTimeRendering = True Dim dt = DateTime.Now Me.RadScheduler1.Appointments.Add(New Appointment(dt.AddMinutes(-10).AddSeconds(1), Now, "A1")) Me.RadScheduler1.Appointments.Add(New Appointment(dt.AddMinutes(-15), DateTime.Now.AddMinutes(-10), "A2")) Me.RadScheduler1.GetTimelineView().StartDate = DateAdd(DateInterval.Minute, -15, Now) Dim customScale As CustomTimescalePerMinute = New CustomTimescalePerMinute() Dim timelineView As SchedulerTimelineView = Me.RadScheduler1.GetTimelineView() timelineView.SchedulerTimescales.Add(customScale) timelineView.ShowTimescale(customScale) Dim currentScaling As SchedulerTimescale = timelineView.GetScaling() currentScaling.DisplayedCellsCount = 15 End Sub End Class Public Class CustomTimescalePerMinute Inherits MinutesTimescale Public Overrides ReadOnly Property ScalingFactor() As Integer Get Return 1 End Get End Property End Class Note: the attached gif file illustrates the behavior. Initially, the first appointment's end is not rendered in the correct time slot. After scrolling, it is displayed correctly. Workaround: force scrolling Private Sub Form1_Load(sender As Object, e As EventArgs) Handles MyBase.Load Dim t As SchedulerTimelineViewElement = TryCast(Me.RadScheduler1.SchedulerElement.ViewElement, SchedulerTimelineViewElement) Dim value = t.NavigationElement.Value t.NavigationElement.Value += 1 Me.RadScheduler1.SchedulerElement.RefreshViewElement() t.NavigationElement.Value = value End Sub
To reproduce: public Form1() { InitializeComponent(); this.radScheduler1.ActiveViewType = SchedulerViewType.Month; this.radScheduler1.Appointments.Add(new Appointment(new DateTime(9999,12,22),TimeSpan.FromMinutes(30),"A1")); }
To reproduce: RadScheduler radScheduler1 = new RadScheduler(); public Form1() { InitializeComponent(); this.Controls.Add(this.radScheduler1); this.radScheduler1.Dock = DockStyle.Fill; Timer timer = new Timer(); timer.Interval = 1000; timer.Tick += timer_Tick; this.radScheduler1.ActiveViewType = SchedulerViewType.Timeline; SetupView(DateTime.Now.Date); timer.Start(); } private void SetupView(DateTime currentDateTime) { SchedulerTimelineView timelineView = radScheduler1.GetTimelineView(); timelineView.RangeStartDate = currentDateTime; timelineView.RangeEndDate = currentDateTime.AddHours(23).AddMinutes(59).AddSeconds(59); timelineView.StartDate = currentDateTime; radScheduler1.FocusedDate = currentDateTime; var scale = Timescales.Hours; timelineView.ShowTimescale(scale); var currentScaling = timelineView.GetScaling(); currentScaling.DisplayedCellsCount = 24; this.radScheduler1.SchedulerElement.RefreshViewElement(); } int count = 1; private void timer_Tick(object sender, EventArgs e) { SetupView(DateTime.Now.AddDays(++count)); } Workaround: SchedulerTimelineView .ShowNavigationElement = false;
To reproduce: public RadRibbonForm1() { InitializeComponent(); this.radScheduler1.FocusedDate = new DateTime(2016, 1, 1); this.radScheduler1.ActiveViewType = Telerik.WinControls.UI.SchedulerViewType.Timeline; SchedulerTimelineView timelineView = this.radScheduler1.GetTimelineView(); timelineView.RangeStartDate = new DateTime(2016, 1, 1, 00, 00, 00); timelineView.RangeEndDate = new DateTime(2016, 12, 31, 23, 59, 59); timelineView.StartDate = new DateTime(2016, 1, 1, 00, 00, 00); Appointment appointment = new Appointment(new DateTime(2016, 1, 1, 00, 00, 00), new DateTime(2016, 1, 10, 00, 00, 00), "Quarter 1"); Appointment appointment2 = new Appointment(new DateTime(2016, 2, 1, 00, 00, 00), new DateTime(2016, 2, 10, 00, 00, 00), "Quarter 1"); Appointment appointment3 = new Appointment(new DateTime(2016, 4, 1, 00, 00, 00), new DateTime(2016, 4, 10, 00, 00, 00), "Quarter 2"); Appointment appointment4 = new Appointment(new DateTime(2016, 5, 1, 00, 00, 00), new DateTime(2016, 6, 10, 00, 00, 00), "Quarter 2"); Appointment appointment5 = new Appointment(new DateTime(2016, 7, 1, 00, 00, 00), new DateTime(2016, 7, 10, 00, 00, 00), "Quarter 3"); Appointment appointment6 = new Appointment(new DateTime(2016, 8, 1, 00, 00, 00), new DateTime(2016, 8, 10, 00, 00, 00), "Quarter 3"); Appointment appointment7 = new Appointment(new DateTime(2016, 11, 1, 00, 00, 00), new DateTime(2016, 11, 10, 00, 00, 00), "Quarter 4"); Appointment appointment8 = new Appointment(new DateTime(2016, 12, 1, 00, 00, 00), new DateTime(2016, 12, 10, 00, 00, 00), "Quarter 4"); this.radScheduler1.Appointments.Add(appointment); this.radScheduler1.Appointments.Add(appointment2); this.radScheduler1.Appointments.Add(appointment3); this.radScheduler1.Appointments.Add(appointment4); this.radScheduler1.Appointments.Add(appointment5); this.radScheduler1.Appointments.Add(appointment6); this.radScheduler1.Appointments.Add(appointment7); this.radScheduler1.Appointments.Add(appointment8); QuarterTimescale qTimeScale = new QuarterTimescale(); qTimeScale.DisplayedCellsCount = 4; timelineView.SchedulerTimescales.Add(qTimeScale); this.radScheduler1.GetTimelineView().ShowTimescale(qTimeScale); } class QuarterTimescale : MonthTimescale { public override int ScalingFactor { get { return 3; } } public override string Name { get { return "Quarter"; } } }
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; } }
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.
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); } }
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: 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.
To reproduce: public Form1() { InitializeComponent(); this.radScheduler1.Appointments.Add(new Appointment(DateTime.Today.AddHours(1),TimeSpan.FromHours(3),"Meeting")); this.radScheduler1.ActiveViewType = SchedulerViewType.Week; this.radScheduler1.GetWeekView().RangeFactor = ScaleRange.HalfHour; this.radScheduler1.SchedulerElement.DragDropBehavior.AutoScrollDayViewOnDrag = true; this.Size = new Size(800, 350); } It's necessary to stretch down the application so that a few hours are shown (let's say 4 hours) and the appointment is a bit less, for example 3 hours. If you look at the gif, I am scrolling down around 14, then I'm stopping a bit, while always keeping the mouse button pressed, and then I start scrolling up: at that time the scroll results in going down until 19, instead of going up. Workaround: this.radScheduler1.SchedulerElement.DragDropBehavior = new CustomAppointmentDraggingBehavior(this.radScheduler1.SchedulerElement); public class CustomAppointmentDraggingBehavior : AppointmentDraggingBehavior { public CustomAppointmentDraggingBehavior(SchedulerVisualElement activeOwner) : base(activeOwner) { } protected override void HandleMouseMove(Point mousePos) { base.HandleMouseMove(mousePos); DayViewAppointmentsTable table = this.ActiveOwner.Scheduler.DragDropBehavior.ActiveOwner as DayViewAppointmentsTable; if (table != null && this.ActiveOwner.Scheduler.DragDropBehavior.AutoScrollDayViewOnDrag) { Point pt = table.PointFromScreen(Control.MousePosition); FieldInfo fi = typeof(DayViewAppointmentsTable).GetField("lastMovingPoint", System.Reflection.BindingFlags.NonPublic | System.Reflection.BindingFlags.Instance); fi.SetValue(table, pt); } } }
Workaround: subscribe to the PanGesture event and set the StartDate property of the current view to the desired new date.
To reproduce: - Bind the scheduler to the default SchedulerData.mdb - Add an appointment like this: this.radScheduler1.Appointments.BeginUpdate(); Appointment appointment = CreateAppointment(); this.radScheduler1.Appointments.Add(appointment); this.radScheduler1.Appointments.EndUpdate(); - Save the database