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.
The creation/removal itself will be triggered from separate pages.
Visual Studio will create the basic structure of the solution for us, including three platform-specific projects and one portable class library.
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.
The Android platform requires installation of the following additional packages:
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.
In the console first select X_Calendar.Droid project:
Then, execute the following commands:
Having this information in mind, we will need to add references to the following binaries in our solution:
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.
Android
In Android we need to add the following code right after the using statements of the MainActivity class:
The MainActivity.cs file should look similar to this:
iOS
We can continue to the iOS project. The following code should be added in the AppDelegate class:
The AppDelegate.cs file should look similar to this:
Windows Phone
In the WinPhone project we need to add the following code in the MainPage.xaml.cs file:
It should look like this:
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 :
Defining the Appointments Collection
For this part, let’s define a static field which holds all the appointments visualized in the RadCalendar component:
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.
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:
In the code behind of our AppointmentsPage, we will also use the same navigation mechanism.
This completes the raw layout of our application.
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:
The code behind this page handles the button click event and, based on the user selection, creates an appointment.
The code behind this page will handle the click of the button, which will delete the selected appointment like this:
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:
You can find the complete project at GitHub. Of course, to run it, you need to download Telerik UI for Xamarin.
Happy coding!
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.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.Visual Studio will create the basic structure of the solution for us, including three platform-specific projects and one portable class library.
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
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.
In the console first select X_Calendar.Droid project:
Then, execute the following commands:
- Install-Package Xamarin.Android.Support.v7.AppCompat
- Install-Package Xamarin.Android.Support.v7.RecyclerView
- Install-Package Xamarin.Android.Support.v8.RenderScript
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
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"
?>
<
ContentPage
xmlns
=
"http://xamarin.com/schemas/2014/forms"
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"
?>
<ContentPage xmlns=
"http://xamarin.com/schemas/2014/forms"
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"
?>
<
ContentPage
xmlns
=
"http://xamarin.com/schemas/2014/forms"
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:
You can find the complete project at GitHub. Of course, to run it, you need to download Telerik UI for Xamarin.
Happy coding!