Custom Calendar Renderer

Sometimes, you might find that certain feature is available in the native control on a given platform, but is not exposed in Xamarin Forms or you might want to customize the calendar look for each platform. This is when you would need to create a custom renderer. This will allow you to access the native control and configure it as per your needs.

The native Calendar control documentation can be found here.

Example

Let us consider the following example: we need to customize how the calendar looks on Android. Create a class which inherits from Telerik.XamarinForms.InputRenderer.Android.CalendarRenderer and override the OnElementChanged method:

[assembly: ExportRenderer(typeof(CustomCalendar), typeof(CustomCalendarRenderer))]
namespace SDKBrowser.Droid.Calendar.Styling.CustomRenderer
{
    public class CustomCalendarRenderer : CalendarRenderer
    {
        protected override void OnElementChanged(ElementChangedEventArgs<RadCalendar> e)
        {
            base.OnElementChanged(e);

            if (this.Control != null)
            {
                this.Control.CustomizationRule = new CustomizationRule();

                this.Control.CellDecorationsLayer.Color = 
                    Android.Graphics.Color.ParseColor("#0044FF");
            }
        }
    }
}

The CellDecorationsLayer.Color property changes the border color of the currently selected cell. The CustomizationRule property takes an object which implements the Com.Telerik.Android.Common.IProcedure interface:

public class CustomizationRule : Java.Lang.Object, IProcedure
{
    private Java.Util.Calendar calendar = Java.Util.Calendar.Instance;

    public void Apply(Java.Lang.Object p0)
    {
        if (!(p0 is CalendarDayCell))
        {
            return;
        }

        CalendarDayCell calendarCell = p0.JavaCast<CalendarDayCell>();
        if (calendarCell.CellType != CalendarCellType.Date)
        {
            return;
        }

        calendarCell.SetBackgroundColor(
            Android.Graphics.Color.ParseColor("#F8F8F8"), // used when the cell is enabled
            Android.Graphics.Color.ParseColor("#E0E0E0")); // used when the cell is disabled

        calendarCell.SetTextColor(
            Android.Graphics.Color.ParseColor("#000000"), // used when the cell is enabled
            Android.Graphics.Color.ParseColor("#FFFFFF")); // used when the cell is disabled

        calendar.TimeInMillis = calendarCell.Date;

        var weekDay = calendar.Get(Java.Util.CalendarField.DayOfWeek);
        if (weekDay == 1 || weekDay == 7)
        {
            calendarCell.SetBackgroundColor(
                Android.Graphics.Color.ParseColor("#EEEEEE"), // used when the cell is enabled
                Android.Graphics.Color.ParseColor("#E0E0E0")); // used when the cell is disabled

            calendarCell.SetTextColor(
                Android.Graphics.Color.ParseColor("#999999"), // used when the cell is enabled
                Android.Graphics.Color.ParseColor("#AAAAAA")); // used when the cell is disabled
        }

        var currentDate = Java.Util.Calendar.Instance.Get(Java.Util.CalendarField.Date);
        var currentMoth = Java.Util.Calendar.Instance.Get(Java.Util.CalendarField.Month);
        var currentYear = Java.Util.Calendar.Instance.Get(Java.Util.CalendarField.Year);

        var boldTypeface = Android.Graphics.Typeface.Create(
                calendarCell.TextPaint.Typeface, Android.Graphics.TypefaceStyle.Bold);

        if (calendar.Get(Java.Util.CalendarField.Date) == currentDate &&
            calendar.Get(Java.Util.CalendarField.Month) == currentMoth &&
            calendar.Get(Java.Util.CalendarField.Year) == currentYear)
        {
            calendarCell.BorderColor = Android.Graphics.Color.ParseColor("#00FF44");
            calendarCell.BorderWidth = Forms.Context.ToPixels(2);

            calendarCell.Typeface = boldTypeface;
        }

        if (calendarCell.Selected)
        {
            calendarCell.Typeface = boldTypeface;
        }
    }
}

Here is the result:

Custom Calendar Renderer