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);
}
}
}
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:
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:
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);
}
}
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:
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.
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:
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: Resource lResource; var LColors = new Color[5]; SchedulerMultiDayView multyDayView; DateTime startDate; int interval; radScheduler1.Statuses.Add(new AppointmentStatusInfo(5, "New", Color.Green, Color.Green, AppointmentStatusFillType.Solid)); radScheduler1.Statuses.Add(new AppointmentStatusInfo(6, "ACCP", Color.DarkOrange, Color.DarkOrange, AppointmentStatusFillType.Solid)); lResource = new Resource(); lResource.Id = new EventId(1); lResource.Name = "Bert"; lResource.Color = Color.Red; radScheduler1.Resources.Add(lResource); radScheduler1.ActiveView.ShowHeader = true; this.radScheduler1.ActiveViewType = SchedulerViewType.MultiDay; multyDayView = this.radScheduler1.GetMultiDayView(); startDate = DateTime.Today; interval = 30; radScheduler1.GroupType = GroupType.Resource; multyDayView.Intervals.Add(startDate, interval); multyDayView.RulerScaleSize = 4; radScheduler1.EnableExactTimeRendering = true; multyDayView.RangeFactor = ScaleRange.Hour;
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 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");
this.radScheduler1.Appointments.Add(appointment);
}
private void radCheckBox1_ToggleStateChanged(object sender, Telerik.WinControls.UI.StateChangedEventArgs args)
{
this.radScheduler1.EnableExactTimeRendering = this.radCheckBox1.Checked;
}
Please refer to the attached gif file.
Workaround:
In order to deal with the border case with appointment ending at 00:00h, use a new TimeSpan(0,14,59)
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:
public Form1()
{
InitializeComponent();
this.radScheduler1.ActiveViewType = SchedulerViewType.Month;
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);
this.radScheduler1.EnableExactTimeRendering = true;
}
Click "This month" in RadSchedulerNavigator.
Workaround: In order to deal with the border case with appointment ending at 00:00h, use a new TimeSpan(0,14,59)
Broken in version R3 2016 (2016.3.913)
How to reproduce:
SchedulerDayViewElement dayViewElement = (SchedulerDayViewElement)this.radScheduler1.ViewElement;
dayViewElement.SetColumnWidth(1, 2);
Workaround:
IDictionary cachedSum = (IDictionary)dayViewElement.GetType().GetField("cachedSum", BindingFlags.Instance | BindingFlags.NonPublic).GetValue(dayViewElement);
cachedSum.Clear();
IDictionary cachedColumnHorizontalOffset = (IDictionary)dayViewElement.GetType().GetField("cachedColumnHorizontalOffset", BindingFlags.Instance | BindingFlags.NonPublic).GetValue(dayViewElement);
cachedColumnHorizontalOffset.Clear();
SchedulerDayViewElement dayViewElement = (SchedulerDayViewElement)this.radScheduler1.ViewElement;
dayViewElement.SetColumnWidth(1, 2);
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
How to reproduce:
Public Class Form1
Sub New()
InitializeComponent()
End Sub
Protected Overrides Sub OnLoad(e As EventArgs)
MyBase.OnLoad(e)
Me.SetUpScheduler()
For i As Integer = 0 To 0
Dim app As New Appointment(DateTime.Now.AddHours(1), TimeSpan.FromMinutes(60), "Summary" & i, "Description1")
app.ResourceId = Me.RadScheduler1.Resources(i).Id
Me.RadScheduler1.Appointments.Add(app)
Dim app2 As New Appointment(DateTime.Now.AddHours(3), TimeSpan.FromMinutes(60), "Summary" & i, "Description2")
app2.BackgroundId = 2
app2.ResourceId = Me.RadScheduler1.Resources(i).Id
Me.RadScheduler1.Appointments.Add(app2)
Dim recurringAppointment As New Appointment(DateTime.Now, TimeSpan.FromMinutes(60), "Recurring" & i, "Recurring Appointment")
recurringAppointment.BackgroundId = 4
recurringAppointment.ResourceId = Me.RadScheduler1.Resources(i).Id
recurringAppointment.RecurrenceRule = New DailyRecurrenceRule(DateTime.Now, 1, 10)
Me.RadScheduler1.Appointments.Add(recurringAppointment)
Next
'AddHandler Me.RadScheduler1.CellPrintElementFormatting, AddressOf RadScheduler1_CellPrintElementFormatting
End Sub
Private Sub SetUpScheduler()
Dim colors As Color() = New Color() {Color.LightBlue, Color.LightGreen, Color.LightYellow, Color.Red, Color.Orange, Color.Pink, _
Color.Purple, Color.Peru, Color.PowderBlue}
'Dim names As String() = New String() {"Alan Smith", "Anne Dodsworth", "Boyan Mastoni", "Richard Duncan", "Maria Schneider"}
Dim names As String() = New String() {"Rick Astley"}
For i As Integer = 0 To names.Length - 1
Dim resource As New Resource()
resource.Id = New EventId(i)
resource.Name = names(i)
resource.Color = colors(i)
Me.RadScheduler1.Resources.Add(resource)
Next
Me.RadScheduler1.ActiveView.ResourcesPerView = 1
Me.RadScheduler1.GroupType = GroupType.Resource
Me.RadSchedulerNavigator1.SchedulerNavigatorElement.TimeZonesElementLayout.Visibility = ElementVisibility.Collapsed
Me.RadSchedulerNavigator1.ShowWeekendCheckBox.Visibility = ElementVisibility.Collapsed
Me.RadSchedulerNavigator1.SchedulerNavigatorElement.MonthViewButton.Visibility = ElementVisibility.Collapsed
Me.RadSchedulerNavigator1.SchedulerNavigatorElement.TimelineViewButtonVisible = False
End Sub
Private Sub RadButton1_Click(sender As Object, e As EventArgs) Handles RadButton1.Click
Me.PrintScheduler(Me.RadScheduler1)
End Sub
Private Sub PrintScheduler(radScheduler As RadScheduler)
Dim doc As RadPrintDocument = New RadPrintDocument
doc.AssociatedObject = radScheduler
Dim schedulerPrintStyle As Telerik.WinControls.UI.SchedulerPrintStyle = Nothing
Select Case Me.RadScheduler1.ActiveViewType
Case SchedulerViewType.Day
schedulerPrintStyle = New SchedulerDailyPrintStyle()
'schedulerPrintStyle = New CustomRadSchedulerDailyPrintStyle()
Case SchedulerViewType.Week, SchedulerViewType.WorkWeek
schedulerPrintStyle = New SchedulerWeeklyCalendarPrintStyle()
'schedulerPrintStyle = New CustomSchedulerWeeklyCalendarPrintStyle()
End Select
schedulerPrintStyle.DateStartRange = radScheduler.ActiveView.StartDate
schedulerPrintStyle.DateEndRange = radScheduler.ActiveView.EndDate
schedulerPrintStyle.TimeStartRange = TimeSpan.FromMinutes(5)
schedulerPrintStyle.TimeEndRange = TimeSpan.FromHours(23).Add(TimeSpan.FromMinutes(59))
schedulerPrintStyle.AppointmentFont = New Font("Consolas", 8.5)
schedulerPrintStyle.GroupType = SchedulerPrintGroupType.Resource
AddHandler schedulerPrintStyle.CellElementFormatting, AddressOf radSchedWork_PrintSchedulerCellElementFormatting
radScheduler.PrintStyle = schedulerPrintStyle
radScheduler.PrintPreview()
End Sub
Private Sub radSchedWork_PrintSchedulerCellElementFormatting(sender As Object, e As PrintSchedulerCellEventArgs)
e.CellElement.BackColor = Color.White
e.CellElement.DrawFill = False
Dim cell As SchedulerPrintCellElement = TryCast(e.CellElement, SchedulerPrintCellElement)
If cell IsNot Nothing Then
Dim msg As String = "PrintSchedulerCellElementFormatting for Date {0}"
Debug.Print(String.Format(msg, e.CellElement.Date))
'If cell.DateFormat = "hh:mm" Then
' cell.DateFormat = "hh:mm tt"
'ElseIf cell.DateFormat = "dd MMM" Then
' cell.DateFormat = "dd ddd"
'Else
e.CellElement.DrawFill = True
If e.CellElement.[Date].Hour Mod 2 = 0 Then
If e.CellElement.[Date].Day Mod 2 = 0 Then
e.CellElement.BackColor = Color.LightSalmon
Else
e.CellElement.BackColor = Color.LightBlue
End If
Else
e.CellElement.BackColor = Color.LightGreen
End If
'End If
End If
End Sub
Private Sub RadScheduler1_CellFormatting(sender As Object, e As SchedulerCellEventArgs) Handles RadScheduler1.CellFormatting
'reset all properties for cells that may be changed here
e.CellElement.BackColor = Color.White
e.CellElement.DrawFill = False
If e.CellElement.[Date].Hour Mod 2 = 0 Then
e.CellElement.DrawFill = True
If e.CellElement.[Date].Day Mod 2 = 0 Then
e.CellElement.BackColor = Color.LightSalmon
Else
e.CellElement.BackColor = Color.LightBlue
End If
Else
e.CellElement.BackColor = Color.LightGreen
End If
End Sub
End Class
Workaround: Private Sub PrintScheduler(radScheduler As RadScheduler)
Dim doc As RadPrintDocument = New RadPrintDocument
doc.AssociatedObject = radScheduler
Dim schedulerPrintStyle As Telerik.WinControls.UI.SchedulerPrintStyle = Nothing
Select Case Me.RadScheduler1.ActiveViewType
Case SchedulerViewType.Day
'schedulerPrintStyle = New SchedulerDailyPrintStyle()
schedulerPrintStyle = New CustomRadSchedulerDailyPrintStyle()
Case SchedulerViewType.Week, SchedulerViewType.WorkWeek
'schedulerPrintStyle = New SchedulerWeeklyCalendarPrintStyle()
schedulerPrintStyle = New CustomSchedulerWeeklyCalendarPrintStyle()
End Select
schedulerPrintStyle.DateStartRange = radScheduler.ActiveView.StartDate
schedulerPrintStyle.DateEndRange = radScheduler.ActiveView.EndDate
schedulerPrintStyle.TimeStartRange = TimeSpan.FromMinutes(5)
schedulerPrintStyle.TimeEndRange = TimeSpan.FromHours(23).Add(TimeSpan.FromMinutes(59))
schedulerPrintStyle.AppointmentFont = New Font("Consolas", 8.5)
schedulerPrintStyle.GroupType = SchedulerPrintGroupType.Resource
AddHandler schedulerPrintStyle.CellElementFormatting, AddressOf radSchedWork_PrintSchedulerCellElementFormatting
radScheduler.PrintStyle = schedulerPrintStyle
radScheduler.PrintPreview()
End Sub
Public Class CustomRadSchedulerDailyPrintStyle
Inherits SchedulerDailyPrintStyle
Private currentPage As Integer
Public Overrides Sub DrawPage(graphics As Graphics, drawingArea As Rectangle, pageNumber As Integer)
Me.currentPage = pageNumber
MyBase.DrawPage(graphics, drawingArea, pageNumber)
End Sub
Protected Overrides Sub DrawCells(appArea As Rectangle, graphics As Graphics)
Dim currentDate = Me.GetPageDate(Me.currentPage)
Dim rowCount As Single = Math.Max(1, CInt(Math.Ceiling((TimeEndRange - TimeSpan.FromHours(TimeStartRange.Hours)).TotalHours)))
Dim rowHeight As Single = CSng(appArea.Height) / rowCount
For row As Integer = 0 To rowCount - 1
Dim headerCellRect As New RectangleF(appArea.X, appArea.Y + row * rowHeight, Me.HoursColumnWidth, rowHeight)
Dim element As New SchedulerPrintCellElement()
element.DrawBorder = True
element.Font = Me.DateHeadingFont
element.[Date] = currentDate.AddHours(CInt(TimeStartRange.Add(TimeSpan.FromHours(row)).TotalHours))
element.DateFormat = "hh:mm"
element.TextAlignment = ContentAlignment.TopRight
Me.DrawCell(element, graphics, headerCellRect)
element.DrawText = False
Dim numberOfSubRows As Integer = 1
If Me.Scheduler.ActiveViewType = SchedulerViewType.Day OrElse Me.Scheduler.ActiveViewType = SchedulerViewType.MultiDay OrElse Me.Scheduler.ActiveViewType = SchedulerViewType.Week OrElse Me.Scheduler.ActiveViewType = SchedulerViewType.WorkWeek Then
numberOfSubRows = 60 / CInt(DirectCast(Me.Scheduler.ActiveView, SchedulerDayViewBase).RangeFactor)
End If
For i As Integer = 0 To numberOfSubRows - 1
Dim rect As New RectangleF(appArea.X + HoursColumnWidth, appArea.Y + row * rowHeight + rowHeight / numberOfSubRows * i, appArea.Width - HoursColumnWidth, rowHeight / numberOfSubRows)
If i = numberOfSubRows - 1 Then
rect.Height += (appArea.Y + (row + 1) * rowHeight) - (rect.Y + rect.Height)
End If
Me.DrawCell(element, graphics, rect)
Next
Next
End Sub
End Class
Public Class CustomSchedulerWeeklyCalendarPrintStyle
Inherits SchedulerWeeklyCalendarPrintStyle
Protected Overrides Sub DrawCells(appArea As RectangleF, graphics As Graphics, pageNumber As Integer)
Dim days As Integer = Me.GetNumberOfDays(pageNumber)
Dim currentDate As DateTime = Me.GetPageDate(pageNumber)
If Me.TwoPagesPerWeek AndAlso pageNumber Mod 2 = 0 Then
'page numbers are 1-based
currentDate = currentDate.AddDays(Me.GetNumberOfDays(pageNumber - 1))
End If
Dim rowCount As Single = Math.Max(1, CInt(Math.Ceiling((TimeEndRange - TimeSpan.FromHours(TimeStartRange.Hours)).TotalHours)))
Dim rowHeight As Single = CSng(appArea.Height) / rowCount
Dim columnWidth As Single = (appArea.Width - Me.HoursColumnWidth) / CSng(days)
For row As Integer = 0 To rowCount - 1
Dim headerCellRect As New RectangleF(appArea.X, appArea.Y + row * rowHeight, Me.HoursColumnWidth, rowHeight)
Dim element As New SchedulerPrintCellElement()
element.DrawBorder = True
element.Font = Me.DateHeadingFont
element.[Date] = DateTime.Today.AddHours(CInt(TimeStartRange.Add(TimeSpan.FromHours(row)).TotalHours))
element.[Date] = currentDate.AddHours(CInt(TimeStartRange.Add(TimeSpan.FromHours(row)).TotalHours))
element.DateFormat = "hh:mm"
element.TextAlignment = ContentAlignment.TopRight
Me.DrawCell(element, graphics, headerCellRect)
element.DrawText = False
Dim numberOfSubRows As Integer = 60 / CInt(DirectCast(Me.Scheduler.ActiveView, SchedulerDayViewBase).RangeFactor)
For i As Integer = 0 To numberOfSubRows - 1
Dim rect As New RectangleF(appArea.X + HoursColumnWidth, appArea.Y + row * rowHeight + rowHeight / numberOfSubRows * i, appArea.Width - HoursColumnWidth, rowHeight / numberOfSubRows)
If i = numberOfSubRows - 1 Then
rect.Height += (appArea.Y + (row + 1) * rowHeight) - (rect.Y + rect.Height)
End If
Me.DrawCell(element, graphics, rect)
Next
For j As Integer = 0 To days - 1
element = New SchedulerPrintCellElement()
element.DrawBorder = True
element.DrawText = False
element.[Date] = currentDate.AddDays(j).AddHours(CInt(TimeStartRange.Add(TimeSpan.FromHours(row)).TotalHours))
Dim rect As New RectangleF(appArea.X + HoursColumnWidth + j * columnWidth, appArea.Y + row * rowHeight, columnWidth, rowHeight)
Me.DrawCell(element, graphics, rect)
Next
Next
End Sub
End Class
To reproduce: please refer to the attached sample project and gif file illustrating the visual problem.
Workaround: subscribe to the RadSchedulerNavigator.ShowWeekendStateChanged event and refresh the scheduler view element:
AddHandler Me.RadSchedulerNavigator1.ShowWeekendStateChanged, AddressOf ShowWeekendStateChanged
Private Sub ShowWeekendStateChanged(sender As Object, args As StateChangedEventArgs)
Me.RadScheduler1.SchedulerElement.RefreshViewElement()
End Sub
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:
Private Sub RadForm1_Load(sender As Object, e As EventArgs) Handles MyBase.Load
Dim dayView As SchedulerDayView = Me.RadScheduler1.GetDayView()
dayView.RangeFactor = ScaleRange.FiveMinutes
Dim ruler As RulerPrimitive = TryCast(Me.RadScheduler1.SchedulerElement.ViewElement, _
SchedulerDayViewElement).DataAreaElement.Ruler
ruler.FormatStrings = New RulerFormatStrings("hh", "mm", "hh", "mm")
End Sub
Add a RadScheduler to a form and use the code snippet above. Run the application and scroll to the current time to see the current time indicator. Leave the form opened so you can see it on the second monitor but focus on another application for 5 minutes. You will notice that the current time indicator won't be redrawn until you focus RadScheduler again, click on the view or perform scrolling. The expected behavior is that RadScheduler will move the current time indicator as time is ticking.
Workaround: use a timer to refresh RadScheduler at a certain interval:
Dim timer As New Timer
timer.Interval = 1000
AddHandler timer.Tick, AddressOf TimerTick
timer.Start()
Private Sub TimerTick(sender As Object, e As EventArgs)
Me.RadScheduler1.SchedulerElement.RefreshViewElement()
End Sub