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 UWP. Create a class which inherits from Telerik.XamarinForms.InputRenderer.UWP.CalendarRenderer and override the OnElementChanged method:

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

            if (this.Control != null)
            {
                var content = Window.Current.Content as Frame;
                var page = content.Content as Page;
                var resources = page.Resources;

                this.Control.NormalCellStyle = 
                    new Telerik.UI.Xaml.Controls.Input.CalendarCellStyle()
                {
                    ContentStyle = (Style)resources["NormalCellContentStyle"],
                    DecorationStyle = (Style)resources["NormalCellDecorationStyle"]
                };

                this.Control.SelectedCellStyle =
                    new Telerik.UI.Xaml.Controls.Input.CalendarCellStyle()
                {
                    ContentStyle = (Style)resources["NormalCellContentStyle"],
                    DecorationStyle = (Style)resources["SelectedCellDecorationStyle"]
                };

                this.Control.AnotherViewCellStyle = 
                    new Telerik.UI.Xaml.Controls.Input.CalendarCellStyle()
                {
                    ContentStyle = (Style)resources["AnotherViewCellContentStyle"],
                    DecorationStyle = (Style)resources["AnotherViewCellDecorationStyle"],
                };

                this.Control.CurrentCellStyle =
                    new Telerik.UI.Xaml.Controls.Input.CalendarCellStyle()
                {
                    ContentStyle = (Style)resources["NormalCellContentStyle"],
                    DecorationStyle = (Style)resources["CurrentCellDecorationStyle"],
                };

                this.Control.HighlightedCellStyle =
                    new Telerik.UI.Xaml.Controls.Input.CalendarCellStyle()
                {
                    ContentStyle = (Style)resources["HighlightedCellContentStyle"],
                    DecorationStyle = (Style)resources["HighlightedCellDecorationStyle"],
                };

                this.Control.DayNameCellStyle =
                    new Telerik.UI.Xaml.Controls.Input.CalendarCellStyle()
                {
                    ContentStyle = (Style)resources["DayNameCellContentStyle"],
                    DecorationStyle = (Style)resources["DayNameCellDecorationStyle"],
                };
            }
        }
    }
}

The styles used in the code snippet above are defined in a XAML resource dictionary merged with the main page resources of the application:

<Style x:Key="NormalCellContentStyle" TargetType="TextBlock">
    <Setter Property="FontSize" Value="17" />
    <Setter Property="FontWeight" Value="Bold" />
    <Setter Property="Foreground" Value="Black" />
    <Setter Property="HorizontalAlignment" Value="Center" />
    <Setter Property="VerticalAlignment" Value="Center" />
</Style>

<Style x:Key="NormalCellDecorationStyle" TargetType="Border" >
    <Setter Property="BorderBrush" Value="DarkGray" />
    <Setter Property="BorderThickness" Value="4, 3, 2, 1" />
    <Setter Property="Background" Value="LightGray" />
    <Setter Property="CornerRadius" Value="0" />
</Style>

<Style x:Key="SelectedCellDecorationStyle" TargetType="Border"
       BasedOn="{StaticResource ResourceKey=NormalCellDecorationStyle}" >
    <Setter Property="BorderBrush" Value="SlateGray" />
    <Setter Property="Background" Value="DarkGray" />
</Style>

<Style x:Key="AnotherViewCellContentStyle" TargetType="TextBlock"
       BasedOn="{StaticResource ResourceKey=NormalCellContentStyle}" >
    <Setter Property="FontWeight" Value="ExtraLight" />
    <Setter Property="Foreground" Value="Gray" />
</Style>

<Style x:Key="AnotherViewCellDecorationStyle" TargetType="Border"
       BasedOn="{StaticResource ResourceKey=NormalCellDecorationStyle}" >
    <Setter Property="BorderBrush" Value="DarkGray" />
</Style>

<Style x:Key="CurrentCellDecorationStyle" TargetType="Border"
       BasedOn="{StaticResource ResourceKey=NormalCellDecorationStyle}" >
    <Setter Property="BorderBrush" Value="Green" />
    <Setter Property="Background" Value="Transparent" />
</Style>

<Style x:Key="HighlightedCellContentStyle" TargetType="TextBlock"
       BasedOn="{StaticResource ResourceKey=NormalCellContentStyle}" >
    <Setter Property="FontWeight" Value="Black" />
</Style>

<Style x:Key="HighlightedCellDecorationStyle" TargetType="Border"
       BasedOn="{StaticResource ResourceKey=NormalCellDecorationStyle}" >
    <Setter Property="BorderBrush" Value="Blue" />
</Style>

<Style x:Key="DayNameCellContentStyle" TargetType="TextBlock"
       BasedOn="{StaticResource ResourceKey=NormalCellContentStyle}" >
    <Setter Property="FontWeight" Value="Bold" />
</Style>

<Style x:Key="DayNameCellDecorationStyle" TargetType="Border"
       BasedOn="{StaticResource ResourceKey=NormalCellDecorationStyle}" >
    <Setter Property="BorderBrush" Value="Gray" />
</Style>

Here is the result:

Custom Calendar Renderer