Telerik blogs
Scheduling-based scenarios are quite popular for the mobile environment, in which the end-user is on the go and needs to check what’s next on his schedule, immediately, without accessing his desktop machine. 

In this blog post, we will guide you through the steps of using the RadCalendar component from the Telerik UI for Xamarin suite, explaining key concepts and terms. For this purpose, we will create a simple demo application using the RadCalendar.

Application Requirements, End-User Capabilities and Raw Design

Let’s say we need an appointment-visualizing application the enables users to view, create and delete appointments. To accomplish this, we will use the RadCalendar to visualize the appointments. Alongside the calendar, we will expose two buttons. One for creating and one for removing appointments. 
calendar-rawlayout

The creation/removal itself will be triggered from separate pages. 

Setting Up a Blank Solution with a Ready-to-Use Template

To set up a solution, we will start by creating a blank application. We will use the Blank App (Xamarin.Forms Portable) template provided by Xamarin. This template shares code using a portable class library. Let's name the project X_Calendar.
calendar-newproject

Visual Studio will create the basic structure of the solution for us, including three platform-specific projects and one portable class library.

calendar-solution

The portable project will hold everything that can be shared between the different platforms. The rest of the projects will use the platform-specific code, such as custom renderers. 

Installing NuGet packages

After having the set up solution, we can start installing the necessary NuGet packages. For every project in the solution, we need to update the Xamarin.Forms NuGet Package to the latest version.

The Android platform requires installation of the following additional packages:
  • Xamarin Support Library v4
  • Xamarin Support Library v7 RecyclerView
  • Xamarin Support Library v8 RenderScript
  • Xamarin Support Library v7 AppCompat
The last two are needed by the RadCalendar specifically. Xamarin Support Library v4 is needed by Xamarin.Forms in all cases.

Installing the packages can be done through the Package Manager Console. You can navigate to it from the main menu >> View >> Other Windows >> Package Manager Console.

calendar-packagemanagerconsole

In the console first select X_Calendar.Droid project:

calendar-PMC

Then, execute the following commands:
  1. Install-Package Xamarin.Android.Support.v7.AppCompat
  2. Install-Package Xamarin.Android.Support.v7.RecyclerView
  3. Install-Package Xamarin.Android.Support.v8.RenderScript
The console should report that every package is successfully installed.

Adding the Necessary References

Next, we can proceed with referencing the required assemblies in our solution. Each of the platform-specific projects should refer to the following:
  • Binaries consisting of the Telerik UI for Xamarin components
  • Binaries consisting of Managed Callable Wrappers for the native components
  • Binaries consisting of the Telerik renderers for the components
The names of the binaries consisting of Managed Callable Wrappers for the native components start with Telerik.Xamarin.[platformName]. The binaries consisting of the UI for Xamarin components start with Telerik.XamarinForms. Last but not least, renderers’ binaries are named after the native binary holding the respective UI component, followed by Renderer.[platformName]. They are part of the UI for Xamarin suite, so their full name is Telerik.XamarinForms.[nameOfBinary]Renderer.[platformName].

Having this information in mind, we will need to add references to the following binaries in our solution:
  • In the Portable project:
    • Telerik.XamarinForms.Input.dll
    • Telerik.XamarinForms.Common.dll
  • In the Android project:
    • Telerik.Xamarin.Android.Common.dll
    • Telerik.Xamarin.Android.Input.dll
    • Telerik.Xamarin.Android.Primitives.dll
    • Telerik.XamarinForms.Common.dll
    • Telerik.XamarinForms.Input.dll
    • Telerik.XamarinForms.InputRenderer.Android.dll
  • In the iOS project:
    • Telerik.Xamarin.iOS.dll
    • Telerik.XamarinForms.Input.dll
    • Telerik.XamarinForms.InputRenderer.iOS.dll
    • Telerik.XamarinForms.Common.dll
  • In the WinPhone project:
    • Telerik.Windows.Controls.Input.dll
    • Telerik.Windows.Controls.Primitives.dll
    • Telerik.Windows.Core.dll
    • Telerik.XamarinForms.Input.dll
    • Telerik.XamarinForms.InputRenderer.WinPhone.dll
    • Telerik.XamarinForms.Common.dll

What are Renderers and Wrappers?

Before registering the renderers, it may be a good idea to have few words about the UI for Xamarin suite and the provided renderers. What they are and where their place is?
Each renderer is simply a class deriving from Xamarin.Forms’ ViewRenderer class. This derived class updates the Xamarin component based on the native one and vice versa. In other words, the renderers, together with the callable wrappers, are the “glue” between the native components and the Xamarin UI. If you need to dig deeper into this, you can refer to Xamarin’s Custom Renderers as well as the Architecture articles.

Registering the Required Telerik Renderers

Having this in mind, we can proceed with coupling the provided renderers with the Xamarin UI. This should be done for each of the platforms separately.

Android

In Android we need to add the following code right after the using statements of the MainActivity class:

[assembly: Xamarin.Forms.ExportRenderer(typeof(Telerik.XamarinForms.Input.RadCalendar), typeof(Telerik.XamarinForms.InputRenderer.Android.CalendarRenderer))]

The MainActivity.cs file should look similar to this:

[assembly: Xamarin.Forms.ExportRenderer(typeof(Telerik.XamarinForms.Input.RadCalendar), typeof(Telerik.XamarinForms.InputRenderer.Android.CalendarRenderer))]
 
namespace X_Calendar.Droid
{
    [Activity(Label = "X_Calendar", Icon = "@drawable/icon", MainLauncher = true, ConfigurationChanges = ConfigChanges.ScreenSize | ConfigChanges.Orientation)]
    public class MainActivity : global::Xamarin.Forms.Platform.Android.FormsApplicationActivity
    {
        protected override void OnCreate(Bundle bundle)
        {
            base.OnCreate(bundle);
 
            global::Xamarin.Forms.Forms.Init(this, bundle);
            LoadApplication(new X_Calendar.App());
        }
    }
}

iOS

We can continue to the iOS project. The following code should be added in the AppDelegate class:

[assembly: Xamarin.Forms.ExportRenderer(typeof(Telerik.XamarinForms.Input.RadCalendar), typeof(Telerik.XamarinForms.InputRenderer.iOS.CalendarRenderer))]

The AppDelegate.cs file should look similar to this:

[assembly: Xamarin.Forms.ExportRenderer(typeof(Telerik.XamarinForms.Input.RadCalendar), typeof(Telerik.XamarinForms.InputRenderer.iOS.CalendarRenderer))]
 
namespace X_Calendar.iOS
{
    [Register("AppDelegate")]
    public partial class AppDelegate : global::Xamarin.Forms.Platform.iOS.FormsApplicationDelegate
    {
        public override bool FinishedLaunching(UIApplication app, NSDictionary options)
        {
            new Telerik.XamarinForms.InputRenderer.iOS.CalendarRenderer();
            global::Xamarin.Forms.Forms.Init();
            LoadApplication(new X_Calendar.App());
 
            return base.FinishedLaunching(app, options);
        }
    }
}

Windows Phone

In the WinPhone project we need to add the following code in the MainPage.xaml.cs file:

[assembly: Xamarin.Forms.ExportRenderer(typeof(Telerik.XamarinForms.Input.RadCalendar), typeof(Telerik.XamarinForms.InputRenderer.WinPhone.CalendarRenderer))]

It should look like this:

[assembly: Xamarin.Forms.ExportRenderer(typeof(Telerik.XamarinForms.Input.RadCalendar), typeof(Telerik.XamarinForms.InputRenderer.WinPhone.CalendarRenderer))]
 
namespace X_Calendar.WinPhone
{
    public partial class MainPage : global::Xamarin.Forms.Platform.WinPhone.FormsApplicationPage
    {
        public MainPage()
        {
            InitializeComponent();
            SupportedOrientations = SupportedPageOrientation.PortraitOrLandscape;
 
            global::Xamarin.Forms.Forms.Init();
            LoadApplication(new X_Calendar.App());
        }
    }
}

Defining the Appointment Class and Collection

Before creating the necessary screens, we should define the Appointment class and the collection that holds our list of appointments.
 
Defining the Appointment Class 

As you would expect, the Appointment class should have
at least StartDate, EndDate and Title, so let's define it this way :

using Telerik.XamarinForms.Input;
 
namespace X_Calendar
{
    public class Appointment : IAppointment
    {
        public DateTime EndDate
        {
            get;
            set;
        }
 
        public DateTime StartDate
        {
            get;
            set;
        }
 
        public string Title
        {
            get;
            set;
        }
    }
}

Defining the Appointments Collection

For this part, let’s define a static field which holds all the appointments visualized in the RadCalendar component:
   
namespace X_Calendar
{
    public static class MyStaticFields
    {
        public static ObservableCollection<Appointment> Appointments;
    }
}

All three pages will interact with this field, which is why we decided to define it as static. The static classes provide easy access to resources from multiple points.

Creating the Raw Layout

After creating the blank application, referencing the correct binaries and registering the renderers we are done with setting up the solution. Now we can focus on implementing the earlier mentioned raw layout of the application. For this purpose, we will create a Forms Xaml Page, which will host a Grid panel with three rows--one for each button and one for the RadCalendar.
<?xml version="1.0" encoding="utf-8" ?>
             xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
             xmlns:telerik="clr-namespace:Telerik.XamarinForms.Input;assembly=Telerik.XamarinForms.Input"
             x:Class="X_Calendar.AppointmentsPage">
  <Grid>
    <Grid.RowDefinitions>
      <RowDefinition>
        <RowDefinition.Height>
          <OnPlatform x:TypeArguments="GridLength">
            <OnPlatform.iOS>30</OnPlatform.iOS>
            <OnPlatform.Android>50</OnPlatform.Android>
            <OnPlatform.WinPhone>70</OnPlatform.WinPhone>
          </OnPlatform>
        </RowDefinition.Height>
      </RowDefinition>
      <RowDefinition>
        <RowDefinition.Height>
          <OnPlatform x:TypeArguments="GridLength">
            <OnPlatform.iOS>30</OnPlatform.iOS>
            <OnPlatform.Android>50</OnPlatform.Android>
            <OnPlatform.WinPhone>70</OnPlatform.WinPhone>
          </OnPlatform>
        </RowDefinition.Height>
      </RowDefinition>
      <RowDefinition Height="*"/>
    </Grid.RowDefinitions>
    <Button Grid.Row="0" Text="Add Appointment" Clicked="AddButtonClicked"/>
    <Button Grid.Row="1" Text="Delete Appointment" Clicked="DeleteButtonClicked"/>
    <telerik:RadCalendar Grid.Row="2" x:Name="calendar"/>
  </Grid>
</ContentPage>

For the navigation between the different pages, we will use the built-in navigation mechanism. We'll need to use the NavigationPage. In the constructor of our application, we will set the MainPage to a NavigationPage like this:

public App()
{
    // The root page of your application
    MainPage = new NavigationPage(new AppointmentsPage());
}

In the code behind of our AppointmentsPage, we will also use the same navigation mechanism.

using Telerik.XamarinForms.Input;
 
namespace X_Calendar
{
    public partial class AppointmentsPage : ContentPage
    {
        static AppointmentsPage()
        {
            MyStaticFields.Appointments = new ObservableCollection<Appointment>() { new Appointment() { StartDate = DateTime.Now.AddDays(-1), EndDate = DateTime.Now.AddDays(-1).AddMinutes(1), Title = "Call Steve" } };
            MyStaticFields.Appointments.Add(new Appointment() { StartDate = DateTime.Now, EndDate = DateTime.Now.AddMinutes(1), Title = "Tickets" });
            MyStaticFields.Appointments.Add(new Appointment() { StartDate = DateTime.Now.AddDays(3), EndDate = DateTime.Now.AddDays(3).AddMinutes(1), Title = "Travel" });
        }
 
        public AppointmentsPage()
        {
            InitializeComponent();
 
            this.calendar.AppointmentsSource = MyStaticFields.Appointments;
        }
 
        protected override void OnAppearing()
        {
            base.OnAppearing();
        }
 
        void AddButtonClicked(object sender, EventArgs e)
        {
            Navigation.PushAsync(new AddAppointmentPage(), true);
        }
 
        void DeleteButtonClicked(object sender, EventArgs e)
        {
            Navigation.PushAsync(new DeleteAppointmentPage(), true);
        }
    }
}

This completes the raw layout of our application.

Create a Page to Add an Appointment

Next, we will create a page to add an appointment. This page should allow the user to populate the properties of an Appointment: StartDate, EndDate and Title.

To enable the user to fill in these properties, we can use two DatePickers and one Entry. To arrange them on the page, we will use a combination of StackLayouts like this:

<?xml version="1.0" encoding="utf-8" ?>
             xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
             x:Class="X_Calendar.AddAppointmentPage">
  <StackLayout>
    <Label Text="Add Appointment Page" FontSize="30" VerticalOptions="Center" HorizontalOptions="Center" />
    <StackLayout Orientation="Horizontal">
      <Label Text="Start: "/>
      <DatePicker x:Name="startDatePicker" HorizontalOptions="StartAndExpand"/>
    </StackLayout>
    <StackLayout Orientation="Horizontal">
      <Label Text="End: "/>
      <DatePicker x:Name="endDatePicker" HorizontalOptions="StartAndExpand"/>
    </StackLayout>
    <StackLayout Orientation="Horizontal">
      <Label Text="Title: "/>
      <Entry x:Name="title" WidthRequest="150"/>
    </StackLayout>
    <Button Text="Done" Clicked="DoneButtonClicked" VerticalOptions="Center" HorizontalOptions="Center"/>
  </StackLayout>
</ContentPage>

The code behind this page handles the button click event and, based on the user selection, creates an appointment.
   
public partial class AddAppointmentPage : ContentPage
{
    public AddAppointmentPage()
    {
        InitializeComponent();
    }
 
    void DoneButtonClicked(object sender, EventArgs e)
    {
        MyStaticFields.Appointments.Add(new Appointment()
        {
            StartDate = startDatePicker.Date,
            EndDate = endDatePicker.Date.AddSeconds(1),
            Title = title.Text == null ? "(No Title)" : title.Text
        });
 
        Navigation.PopAsync(true);
    }
}

Create a Page to Delete an Appointment

Now we proceed with creating a page that will enable the user to delete an appointment. To visualize all available appointments, it should be able to get them and list them in a ListView component. After that, a button click will delete the user selection. To achieve this, we will use a ListView and a Button components like this:

<?xml version="1.0" encoding="utf-8" ?>
             xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
             x:Class="X_Calendar.DeleteAppointmentPage">
  <StackLayout>
    <Label Text="Delete Appointment" FontSize="30" VerticalOptions="Center" HorizontalOptions="Center" />
    <Grid>
      <Grid.RowDefinitions>
        <RowDefinition Height="50"/>
        <RowDefinition Height="*"/>
        <RowDefinition Height="50"/>
      </Grid.RowDefinitions>
      <Label Text="Select appointment to delete"/>
      <ListView x:Name="list" Grid.Row="1">
        <ListView.ItemTemplate>
          <DataTemplate>
            <TextCell Text="{Binding Title}" />
          </DataTemplate>
        </ListView.ItemTemplate>
      </ListView>
      <Button Text="Done" Clicked="DeleteButtonClicked" Grid.Row="2"/>
    </Grid>
  </StackLayout>
</ContentPage>

The code behind this page will handle the click of the button, which will delete the selected appointment like this:

public partial class DeleteAppointmentPage : ContentPage
{
    public DeleteAppointmentPage()
    {
        InitializeComponent();
 
        this.list.ItemsSource = MyStaticFields.Appointments;
    }
 
    void DeleteButtonClicked(object sender, EventArgs e)
    {
        MyStaticFields.Appointments.Remove((Appointment)this.list.SelectedItem);
        Navigation.PopAsync();
    }
}

That's it! Now run the project and add a few appointments. Thanks to the underlying native Calendar components coming from UI for iOS, UI for Android and UI for Windows Phone, you get the look and feel appropriate for each platform:
calendar-all

You can find the complete project at GitHub. Of course, to run it, you need to download Telerik UI for Xamarin.

Happy coding!

Update: Check out the newly released Telerik Tagit, a cross-platform native mobile Xamarin app. We give you source code and a six-part walkthrough of how it was created. Check out how we implemented the Calendar control in that app, right here


pavelrpavlov
About the Author

Pavel Pavlov

Pavel has been part of the Progress Telerik team for five years. He has a background in various XAML technologies, including WPF, Silverlight, WinRT and UWP. He is now part of the Telerik UI for Xamarin team at Progress.

Related Posts

Comments

Comments are disabled in preview mode.