Telerik blogs
XamarinT2 Light_1200x303

Introducing our Telerik ToDo App: A beautifully designed and highly performant task management application built with Telerik UI for Xamarin controls.

In our dynamic world, staying focused and organized is imperative for achieving both business and personal objectives, which is why task management mobile applications are so popular. These simple, yet powerful mobile apps are often used as demos or sample use cases to demonstrate the power of a given framework or technology, and Xamarin.Forms is no different. The team behind Telerik UI for Xamarin has crafted a powerful task management application to demonstrate how you can build a successful customer-facing application with Xamarin.Forms and deploy it on Android, iOS and Microsoft mobile devices.

Overview

The Telerik ToDo sample application aims to mimic a real-world consumer facing application. It uses a combination of various technologies and is developed in line with the latest trends in mobile development architecture. Below is a brief overview of the technologies and frameworks used to create the sample Xamairn.Forms application:

  • Entity Framework Core—a lightweight, extensible, open source and cross-platform version of the popular Entity Framework data access technology. Entity Framework is the standard technology when it comes to .NET developers working with various database implementations by using .NET objects as it removes the need of writing custom data-access layers.
  • SQLite—We have chosen SQLite to serve as a SQL database engine for the application. SQLite is the most used database engine in the world. It is built into all mobile phones and most computers and comes bundled inside countless other applications that people use every day.
  • MVVMFresh—a super-light MVVM framework created specifically for Xamarin.Forms. It's designed to be easy, simple and flexible. Some of the important features the framework provides are:
    • PageModel to PageModel Navigation
    • Automatic BindingContext wiring
    • Built-in IOC containers
    • Automatic wiring of Page events and many more.
  • Telerik UI For Xamarin—offers high-quality Xamarin Forms UI components and Visual Studio item templates to enable every developer, regardless of their experience, to build professional-looking modern mobile applications for iOS, Android and UWP.

Application Structure

The different modules of this sample Xamarin.Forms application are separated in folders with names that are descriptive and quite standard for projects of such size. Some of the more important folders we have introduced are:

  • Models: This is where the business objects live.
  • PageModels: The classes used as BindingContext for each separate Page (or view) are located here.
  • Pages: Hosts the different views/pages that the application will present.
  • DataAccess: The classes related to the database used to store the data of the application are located in this folder.
  • Controls: It contains some small additional custom controls which are used within the pages.
  • Services: The application currently contains just a single ToDoService that takes care of storing and updating the data used within the application.

MVVMFresh—A Lightweight MVVM Framework Implementation Designed for Xamarin.Forms

The MVVM pattern is a standard for applications of any scale in the Xamarin world and this is no exception. As mentioned in the overview, the project relies on the MVVMFresh framework to keep the model and pages organized so that the solution can be easily understood by all users who intend to inspect it. The framework is famous in the Xamarin community for being easy and straightforward to use which makes it a perfect fit for the purpose of our project.

In order to connect the views and their models, all you need to do is follow the convention in the naming—each Page should have a corresponding PageModel. For example, the BindingContext of the MainPage will automatically be set to be an instance of the MainPageModel class.

The navigation within the application is pretty simple as well—you can use the CoreMethods property of the FreshBasePageModel class, which is the base class for all the PageModels within the application, to navigate between models.

For more information on the different features the framework supports, you can refer to its documentation which is quite descriptive—MVVM Fresh.

Data Access

As mentioned earlier, we are using EntityFrameworkCore and its built-in ability to easily communicate with an SQLite database to power the data access capability of this Xamairn.Forms sample application. For the purpose, a couple of NuGet packages are installed:

  • Microsoft.EntityFrameworkCore
  • Microsoft.EntityFrameworkCore.SQLite

The classes needed for EF are all located in the DataAccess folder. You can note that there is a DTO folder where the Data Transfer Objects (the objects used to send data between our application and the underlying database) are located. As you can note they are almost identical to the objects within the Models folder and take care of the information we would like to keep in our database. The DomainMapper class contains some methods to convert between these identical objects.

Additionally, we have added some sample items in the database so that the users of the application can see some “to-do” tasks once the application is initially opened. The sample data creation can be viewed in the SeedData class.

The last and final class from the DataAccess layers is the TodoItemContext class which extends the Entity Framework DbContext class. As advised in the official documentation, the DbContext class can be viewed as a session between your application and the database and can be used to query the database or update it with some new information when needed. It consists of DbSets for the different DTO objects we have. This DbContext is extensively used in the ToDoService class where the actual methods of querying and updating the database are implemented.

As the file systems on each mobile technology differ, we have introduced an IDbFileProvider interface which requires its implementations to set up a single method—GetLocalFilePath. А different implementation of the interface is provided by classes in each separate platform in order to create the database in the correct location. The Xamarin.Forms DependencyService approach is used to obtain the different locations according to the platform on which the application is running.

Creating the actual database can be found in the App.xaml.cs file:

public static DataAccess.TodoItemContext CreateDatabase()
{
    IDbFileProvider dbFileProvider = DependencyService.Get<IDbFileProvider>();
    if (dbFileProvider == null)
        return null;
 
    // Database
    string dblocation = dbFileProvider.GetLocalFilePath("tododb.db");
    System.Diagnostics.Debug.WriteLine($"Database location: {dblocation}");
    DataAccess.TodoItemContext ctx = DataAccess.TodoItemContext.Create(dblocation);
    return ctx;
}

Services

Going back to our earlier technology overview, the application services consist of a single ToDoService which takes care of adding, deleting, updating the "to-do" items within the application or simply to get a list of the existing items. Here are a couple of methods that the service provides: the first is used to get a specific "to-do" item from the database and the second one to add a "to-do" item:

public TodoItem GetTodoItem(int id)
{
    return context.TodoItems
        .Where(c => c.ID == id)0
        .Include(c => c.Category)
        .Include(c => c.Alert)
        .ThenInclude(c => c.Alert)
        .Include(c => c.Recurrence)
        .ThenInclude(c => c.Recurrence)
        .Include(c => c.Priority)
        .SingleOrDefault()?.ToModel(true);
}
public async Task<TodoItem> AddTodoItemAsync(TodoItem newItem)
{
    var dto = newItem.ToDTO();
    var entity = this.context.TodoItems.Add(dto);
    try
    {
        await this.context.SaveChangesAsync();
    }
    catch (Exception e)
    {
        System.Diagnostics.Debug.WriteLine(e);
        throw e;
    }
    TodoItem storedItem = GetTodoItem(entity.Entity.ID);
    MessagingCenter.Send<ITodoService, TodoItem>(this, ActionAdd, storedItem);
    return storedItem;}

Frontend Implementation: The UI Layer and Telerik Controls for Xamarin.Forms

We have integrated multiple controls from our Telerik UI for Xamarin suite in the application so we can easily achieve a modern look-and-feel crafted by our design team.

Embedding the controls was easy and straightforward—all you need to do is follow our documentation, which we are always working on so that it is kept up-to-date and contains the right information for you. Even our team members are often using it as a reference when building demo applications or providing examples to our customers.

The application consists of multiple screens so for the purpose of the blog post we will concentrate on some of the more important views and show you the setup behind them.

Introduction Page and RadSlideView

One of the first pages that the user faces is the “Welcome” screen that utilizes the RadSlideView control and its ability to directly set an ItemTemplate, which makes it a great fit for any “Splash Screen” scenario or views where a sliding content is required. The code for bootstrapping the SlideView element is small and tight:

<telerikPrimitives:RadSlideView x:Name="slideView"
                                               Grid.Row="1"
                        Margin="0,38,0,34"
        ItemsSource="{Binding Slides}"
                        ShowButtons="False" 
                        IndicatorColor="#F2F2F3" 
                        SelectedIndicatorColor="#4DA3E0">
          <telerikPrimitives:RadSlideView.ItemTemplate>
              <DataTemplate>
                  <StackLayout Orientation="Vertical"Margin="0,0,0,50" Spacing="0">
                      <Image Source="{Binding Image}"Aspect="AspectFit">
                          <Image.HorizontalOptions>
                              <OnPlatformx:TypeArguments="LayoutOptions" Default="FillAndExpand">
                                  <On Platform="UWP"Value="CenterAndExpand" />
                              </OnPlatform>
                          </Image.HorizontalOptions>
                          <Image.WidthRequest>
                              <OnPlatformx:TypeArguments="x:Double" Default="-1">
                                  <On Platform="UWP"Value="300" />
                              </OnPlatform>
                          </Image.WidthRequest>
                      </Image>
                      <Label Text="{Binding Title}"HorizontalTextAlignment="Center" TextColor="Black" FontSize="Medium"Margin="0,15,0,0" />
                      <Label Text="{Binding Description}"HorizontalTextAlignment="Center" TextColor="#5C5C68"  Margin="0,14,0,0"/>
                  </StackLayout>
              </DataTemplate>
          </telerikPrimitives:RadSlideView.ItemTemplate>
      </telerikPrimitives:RadSlideView>
 

As you can see, just setting the ItemsSource, the ItemTemplate and some additional properties of the control leads to a result which will make every mobile application better and more professional looking. Here is the actual “Welcome page” when the app is initially opened:

Splash Screen Android

Main Page and RadListView

Once the users are familiarized with the most important functionalities of the application in the introduction screen, they are brought to the main page—the actual list of items that the user has in their “to-do” plans. By default, a list in grid format that contains the categories in which the "to-do" items are grouped is shown. The view is solely achieved by including a RadListView control. As one of the more-complex and feature-rich controls in the suite, it can be highly customized so a more distinguished look is achieved. Here are some of its features that we used in this particular view:

  • Grid Layout
<telerikDataControls:RadListView.LayoutDefinition>
    <telerikListView:ListViewGridLayout HorizontalItemSpacing="0"
                            ItemLength="100"
                            SpanCount="2"
                            VerticalItemSpacing="0" />
</telerikDataControls:RadListView.LayoutDefinition>
 
  • Custom Item Styles
<telerikDataControls:RadListView Grid.Row="1"
                      ItemsSource="{Binding Categories}"
                      ItemStyle="{StaticResource UnifiedItemStyle}"
                      SelectedItemStyle="{StaticResource UnifiedItemStyle}"
                      PressedItemStyle="{StaticResource UnifiedItemStyle}"
                      SelectedItem="{Binding SelectedCategory, Mode=TwoWay}">

 

 

  • ItemTemplateSelector
<telerikDataControls:RadListView.ItemTemplateSelector>
      <templateSelectors:RadListViewItemTemplateSelector>
          <templateSelectors:RadListViewItemTemplateSelector.CategoryTemplate>
              <DataTemplate>
                  <telerikListView:ListViewTemplateCell>
                      <telerikListView:ListViewTemplateCell.View>
                          <-- Template for the existing category items -->
                      </telerikListView:ListViewTemplateCell.View>
                  </telerikListView:ListViewTemplateCell>
              </DataTemplate>
          </templateSelectors:RadListViewItemTemplateSelector.CategoryTemplate>
          <templateSelectors:RadListViewItemTemplateSelector.NewCategoryTemplate>
              <DataTemplate>
                  <telerikListView:ListViewTemplateCell>
                      <telerikListView:ListViewTemplateCell.View>
                         <-- Template for the new category item -->
                      </telerikListView:ListViewTemplateCell.View>
                  </telerikListView:ListViewTemplateCell>
              </DataTemplate>
          </templateSelectors:RadListViewItemTemplateSelector.NewCategoryTemplate>
      </templateSelectors:RadListViewItemTemplateSelector>
</telerikDataControls:RadListView.ItemTemplateSelector>

 

Here is how the different categories will be visualized when using such a setup:

Android ListView ToDo

You can check the full setup of the control directly in the application project, which is available to the public in a GitHub repository here.

Clicking on each separate category will open a new screen where the “to-do” items marked with this specific category will be shown. The new view is again accomplished through a RadListView component, this time in a LinearLayout mode. On this page the users have the possibility to mark an item as already done, which will cross off the item, or delete it. RadListView's swiping feature comes to the rescue to achieve these interactions:

Android ListView Swiping

Furthermore, you can navigate to the different to-do items and edit their specific properties from this screen as well by simply clicking on the item.

Alternative Look with RadTreeView

Even at this state, the application contains all the necessary actions for a user to add different items and categories as well as edit them. However, we have decided to provide an additional option for the clients when choosing how the list of items will appear in their application. Instead of using the default Grid-like view, the app provides an option to show the items in a list with categories as groups. In order to show this view, you simply need to click on the hamburger menu on the right where some additional options will appear:

Android Menu

The menu is set as the DrawerContent of a RadSideDrawer control which is used to easily show the options by clicking the button or through a swiping gesture. Clicking on “Linear View” will alter the default layout as explained and lead to the following view:

Android Treeview Expand Collapse

This time we have added a RadTreeView component to achieve the hierarchical appearance of the categories and the items. Clicking the different categories will collapse/expand the list below. When setting up the TreeView component it is important to apply the correct TreeViewDescriptors, which have the ability to apply different Item templates similar to the RadListView element:

<telerikDataControls:RadTreeView x:Name="treeView" Grid.Row="1"
                                 ItemsSource="{Binding Categories}">
    <telerikDataControls:RadTreeView.Descriptors>
        <telerikDataControls:TreeViewDescriptor TargetType="{x:Type models:Category}" DisplayMemberPath="Name" ItemsSourcePath="Items">
            <telerikDataControls:TreeViewDescriptor.ItemTemplate>
                <templateSelectors:RadTreeViewItemTemplateSelector>
                    <templateSelectors:RadTreeViewItemTemplateSelector.CategoryTemplate>
                        <DataTemplate>
                         <!--Category Item Template-->
                        </DataTemplate>
                    </templateSelectors:RadTreeViewItemTemplateSelector.CategoryTemplate>
                    <templateSelectors:RadTreeViewItemTemplateSelector.NewCategoryTemplate>
                        <DataTemplate>
                            <!--New Category Item Template-->
                        </DataTemplate>
                    </templateSelectors:RadTreeViewItemTemplateSelector.NewCategoryTemplate>
                </templateSelectors:RadTreeViewItemTemplateSelector>
            </telerikDataControls:TreeViewDescriptor.ItemTemplate>
        </telerikDataControls:TreeViewDescriptor>
        <telerikDataControls:TreeViewDescriptor TargetType="{x:Type models:TodoItem}" DisplayMemberPath="Name">
            <telerikDataControls:TreeViewDescriptor.ItemTemplate>
                <DataTemplate>
                 <!--ToDo Item template-->
                </DataTemplate>
            </telerikDataControls:TreeViewDescriptor.ItemTemplate>
        </telerikDataControls:TreeViewDescriptor>
    </telerikDataControls:RadTreeView.Descriptors>
</telerikDataControls:RadTreeView>
 

As you can see, separate descriptors are defined for the Category and ToDoItem business objects and a custom ItemTemplateSelector is set for the Category as we aim for an appearance similar to the RadListView.

Once you go through the actual project you will notice that the RadListView component is used on several occasions throughout the application as the control is very versatile and come in handy for lots of common mobile scenarios. Some other elements from the Telerik UI for Xamarin suite that are used throughout the application are the RadButton, RadBorder and RadPopup controls.

Conclusion

The Telerik ToDo sample application is a perfect example of a real-world consumer facing app that can be built with Xamarin.Forms in no time. We hope you like the approach we have chosen for creating the "To-Do" sample Xamarin.Forms app and you will find it useful when considering the overall architecture for your next Xamarin mobile development.

As this blog post aims to familiarize you with the setup and provide just an overview of the technologies, we suggest you check out the actual project which we have made publicly available. You can also review some of the other sample applications we have created as each one represents a unique scenario and uses additional frameworks and technologies.

If you would like to know more about the available controls in the Telerik UI for Xamarin suite, refer to our official documentation or check out our product page. Other useful resources are the available demos in our QSF and SDK Samples applications or the demo apps from the different platform stores—iOS, Android or Microsoft.

As always, your feedback is greatly appreciated, so if you would like to see a combination of the Telerik UI for Xamarin controls and a particular trending technology, let us know either by raising a ticket or writing in the Telerik UI for Xamarin official forum.

You want to take the Telerik ToDo app for a test? Download Telerik UI for Xamarin and head to GitHub for the Telerik ToDo source code.

Want to take a deep dive into the all Xamarin.Forms Sample Applications by Telerik? Download our whitepaper!

The Ultimate Guide to Xamarin.Forms Mobile Development with Real-World Sample Applications


Stefan Nenchev
About the Author

Stefan Nenchev

Stefan was a Technical Support Engineer on the Telerik UI for Xamarin team.

Related Posts

Comments

Comments are disabled in preview mode.