Getting Started with Xamarin Forms and Prism

Ryan Nguyen .NET, Mobile, Technology Snapshot, Xamarin 2 Comments

In this blog, I’ll show you how easy it is to create an Android and iOS application using Xamarin Forms while utilizing Prism.

What is Xamarin.Forms?

Xamarin Forms is a platform that allows developers to create native Android, iOS, and Windows applications while using the beloved C# programming language.

An attractive feature of Xamarin Forms is that it uses a shared C# codebase to create a native user interface specific to their platform. Out of the box, Xamarin provides large collections of controls to get started. It also has the ability to access native platform features, such as camera access, GPS, text to speech, etc, by using the Dependency Service.

What is Prism?

According to the Prism website, Prism is defined as “a framework for building loosely coupled, maintainable, and testable XAML applications in WPF, Windows 10 UWP, and Xamarin Forms. Prism provides an implementation of a collection of design patterns that are helpful in writing well-structured and maintainable XAML applications, including MVVM, dependency injection, commands, EventAggregator, and others.”

In other words, Prism helps users to write better code.

Prerequisites
  • Visual Studio Pro 2017
  • Prism Framework
  • Prism Template Pack (Visual Studio Extensions)
  • Android Emulator or Android Phone
  • XAML Knowledge

To see the source code associated with this demo, please see this repository: https://github.com/ryandnguyen/SimpleBlog.

Initial Setup

  1. Open Visual Studio. Create a new “Prism Blank App (Xamarin.Forms).” This requires “Prism Template Pack” to be installed.

  2. The selection screen offers three different types of dependency injections (DI) to pick from, AutoFac, Dryloc, and Unity.

    You can read more about each type of dependency injections and what works best for you. In this article, we will not focus on the different types of DI and what advantages or disadvantages one has over the other.

  3. The new App solution would look something like this:

  4. Make sure everything works by building and compiling then deploying the app.  After deploying the app to your emulator or phone, you should have something very basic and simple like the image below.

Source Code Layout

The solution contains multiple projects consisting of a C# shared library, Android, and iOS. The shared library project is where all the business logic and coding implementation would lie. The shared library project also shared across all platforms. Each dedicated project (Android, iOS, Windows) allows the end user to develop native codes that are not available in Xamarin Forms.

Views

This folder contains all your views, essentially the User Interface (UI) for your applications. The View is responsible for displaying information to the user and fire events in response to user interactions. The View is written also in Xamarin XAML. More information on Xamarin Forms UI can be found here.

The Prism Template Pack offers users a variety of page templates that could be selected from. Such items include: Prism ViewModel, CarouselPage, ContentPage, MasterDetailPage, and NavigationPage. More information can be obtained here about each type of page. The template helps users by automatically creating the View, Viewmodel, and registering it in the App.cs file.

ViewModels

This folder contains all the ViewModels for your views. Following the MVVM pattern, each view would contain a ViewModel. The ViewModels would essentially serve as the business logic behind the user interface. Prism would automatically wire your ViewModel by looking at all the ViewModels and matching them to the View with the corresponding name. For example, if there’s a ViewModel called MainPageViewModel, it would try to find the View that’s called MainPage.

Let’s Code

Let’s start by expanding our app to something that’s a bit more than a simple label that shows “Welcome to Xamarin Forms and Prism!”.

When we first created our app, the Prism Template automatically creates a Content Page called Mainpage.xaml. This is by default the main page which would display on startup.

Let’s begin by adding a ListView and setting the ItemSource to a collection of blogs.

<?xml version="1.0" encoding="utf-8" ?>
<ContentPage xmlns="http://xamarin.com/schemas/2014/forms"
             xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
             x:Class="SimpleBlog.Views.MainPage"
             xmlns:local="clr-namespace:SimpleBlog.Behaviors"
             Title="{Binding Title}">

    <StackLayout HorizontalOptions="FillAndExpand" VerticalOptions="FillAndExpand">
        <ListView ItemsSource="{Binding Blogs, Mode=TwoWay}" HasUnevenRows="True" SelectedItem="{Binding SelectedBlog}" local:ItemTappedAttached.Command="{Binding NavigateToBlogCommand}">
            <ListView.ItemTemplate>
                <DataTemplate>
                    <ViewCell>
                        <Frame Margin="10" VerticalOptions="FillAndExpand">
                            <Frame.Content>
                                <StackLayout>
                                    <Label Text="{Binding BlogTitle}"/>
                                    <BoxView Color="LightGray" VerticalOptions="FillAndExpand" HeightRequest="1" HorizontalOptions="FillAndExpand" Margin="0,5,0,0" />
                                    <Label Text="{Binding BlogDescription}" LineBreakMode="WordWrap" HeightRequest="100"></Label>
                                </StackLayout>
                            </Frame.Content>
                        </Frame>
                    </ViewCell>
                </DataTemplate>
            </ListView.ItemTemplate>
        </ListView>
    </StackLayout>

</ContentPage>

The next step is to update the MainPageViewModel to include all the properties and commands that the view is bound to. This includes the collections of Blogs, the SelectedBlog and the NavigateToBlogCommand. The Blogs would serve as the collection of blogs for the user to see. The SelectedBlog would serve as the selected item the user selected. The NavigateToBlogCommand is the action that will be performed when the user selects a blog.

For the purpose of making this app simple, I decided to return a list of hard-coded blogs instead of obtaining it from the database or a service.

using Prism.Commands;
using Prism.Navigation;
using SimpleBlog.Models;
using System;
using System.Collections.Generic;

namespace SimpleBlog.ViewModels
{
    public class MainPageViewModel : ViewModelBase
    {
        public DelegateCommand NavigateToBlogCommand { get; private set; }

        private List<Blog> _blogs = new List<Blog>()
        {
            new Blog
            {
                BlogDescription = "olestie lectus rhoncus non. Ut eget metus neque. Cras laoreet quam ligula, in ultricies enim lobortis vitae. Proin sed justo vel quam luctus bibendum. Praesent gravida vehicula nunc, eu aliquet elit vestibulum non. Aliquam aliquam fringilla nunc, eget tincidunt dui finibus vel.",
                BlogTitle = "Blog 1",
                CreatedDate = DateTime.Now,
                CreatedBy = "Ryan Nguyen"
            },

            new Blog
            {
                BlogDescription = "Lorem ipsum dolor sit amet, consectetur adipiscing elit. Etiam a sollicitudin erat. Vestibulum dapibus sagittis risus, sit amet molestie lectus rhoncus non. Ut eget metus neque. Cras laoreet quam ligula, in ultricies enim lobortis vitae. Proin sed justo vel quam luctus bibendum. Praesent gravida vehicula nunc, eu aliquet elit vestibulum non. Aliquam aliquam fringilla nunc, eget tincidunt dui finibus vel. Ut fermentum viverra justo, a vehicula dui dignissim non. Aenean posuere vestibulum felis, eu fringilla nulla. Nam interdum enim nec risus cursus tempus. Integer vestibulum hendrerit metus, a venenatis justo molestie at. Vestibulum nec libero in velit pulvinar pretium non in enim. Nulla pulvinar auctor dolor, eu laoreet quam vehicula nec. Cras vehicula fringilla massa, vitae molestie lectus dignissim sed. Integer suscipit auctor est, eu bibendum turpis aliquam vitae.",
                BlogTitle = "Blog 2",
                CreatedDate = new DateTime(2017,12,30),
                CreatedBy = "Adam Costenbader"
            },


            new Blog
            {
                BlogDescription = "Etiam a sollicitudin erat. Vestibulum dapibus sagittis risus, sit amet molestie lectus rhoncus non. Ut eget metus neque. Cras laoreet quam ligula, in ultricies enim lobortis vitae. Proin sed justo vel quam luctus bibendum. Praesent gravida vehicula nunc, eu aliquet elit vestibulum non. Aliquam aliquam fringilla nunc, eget tincidunt dui finibus vel. Ut fermentum viverra justo, a vehicula dui dignissim non. Aenean posuere vestibulum felis, eu fringilla nulla. Nam interdum enim nec risus cursus tempus. Integer vestibulum hendrerit metus, a venenatis justo molestie at. Vestibulum nec libero in velit pulvinar pretium non in enim. Nulla pulvinar auctor dolor, eu laoreet quam vehicula nec. Cras vehicula fringilla massa, vitae molestie lectus dignissim sed. Integer suscipit auctor est, eu bibendum turpis aliquam vitae.",
                BlogTitle = "Blog 3",
                CreatedDate = new DateTime(2017,11,30),
                CreatedBy = "Rusty Divine"
            },


            new Blog
            {
                BlogDescription = "molestie lectus rhoncus non. Ut eget metus neque. Cras laoreet quam ligula, in ultricies enim lobortis vitae. Proin sed justo vel quam luctus bibendum. Praesent gravida vehicula nunc, eu aliquet elit vestibulum non. Aliquam aliquam fringilla nunc, eget tincidunt dui finibus vel. Ut fermentum viverra justo, a vehicula dui dignissim non. Aenean posuere vestibulum felis, eu fringilla nulla. Nam interdum enim nec risus cursus tempus. Integer vestibulum hendrerit metus, a venenatis justo molestie at. Vestibulum nec libero in velit pulvinar pretium non in enim. Nulla pulvinar auctor dolor, eu laoreet quam vehicula nec. Cras vehicula fringilla massa, vitae molestie lectus dignissim sed. Integer suscipit auctor est, eu bibendum turpis aliquam vitae.",
                BlogTitle = "Blog 4",
                CreatedDate = new DateTime(2017,10,30),
                CreatedBy = "Linh Nguyen"
            },

        };

        private Blog _selectedBlog;
        public Blog SelectedBlog
        {
            get { return _selectedBlog; }
            set { SetProperty(ref _selectedBlog, value); }
        }

        public List<Blog> Blogs
        {
            get { return _blogs; }
            set { SetProperty(ref _blogs, value); }
        }
        public MainPageViewModel(INavigationService navigationService)
            : base(navigationService)
        {
            Title = "Blogs";
            NavigateToBlogCommand = new DelegateCommand(NavigateToBlog, () => SelectedBlog != null).ObservesProperty(() => SelectedBlog);

        }
        private void NavigateToBlog()
        {
            var parameter = new NavigationParameters();
            parameter.Add("Blog", SelectedBlog);
            NavigationService.NavigateAsync("Blog", parameter);
        }
    }
}

At this point, the app should be a scrollable list of blog summaries on the main page.

Navigation

The next step is to allow the user to select the blog and navigate to see the blog details rather than just a snippet. In order to navigate to see the blog details, the MainPageViewModel utilizes the NavigationServiceservice. This service is dependency injected in the constructor, which makes it easily accessible. This service also allows you to pass parameters when navigating.

Looking at the NavigateToBlog method in the MainPageViewModel, we are passing in the SelectedBlog object as a parameter. The Blog page would then consume the object to render the UI to display the blog details. However, since the Blog page does not exist quite yet, the first thing we want to do is create it.

Under the Views folder, add a new Prism Content Page called Blog. This would automatically create the BlogViewModel and automatically register the new page in the App.cs file.

Simply update the Blog and BlogViewModel to the following:

Blog View
<?xml version="1.0" encoding="utf-8" ?>
<ContentPage xmlns="http://xamarin.com/schemas/2014/forms"
             xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
             xmlns:prism="clr-namespace:Prism.Mvvm;assembly=Prism.Forms"
             prism:ViewModelLocator.AutowireViewModel="True"
             Title="{Binding Title}"
             x:Class="SimpleBlog.Views.Blog">

    
    <Frame Margin="10" VerticalOptions="FillAndExpand">
        <Frame.Content>
            <StackLayout VerticalOptions="FillAndExpand">
                <StackLayout HorizontalOptions="FillAndExpand" Orientation="Horizontal">
                    <Label Text="{Binding BlogDetail.BlogTitle}" HorizontalOptions="StartAndExpand"/>
                    <Label Text="{Binding BlogDetail.CreatedBy, StringFormat='Author: {0}'}" HorizontalOptions="End"/>
                </StackLayout>
                
                <BoxView Color="LightGray" HeightRequest="1" HorizontalOptions="FillAndExpand" Margin="0,5,0,0" />
                <Label Text="{Binding BlogDetail.BlogDescription}" LineBreakMode="WordWrap" VerticalOptions="FillAndExpand"></Label>
                <Label Text="{Binding BlogDetail.CreatedDate, StringFormat='Date: {0: MM-dd-yyy}'}" VerticalOptions="End" HorizontalOptions="EndAndExpand"/>
            </StackLayout>
        </Frame.Content>
    </Frame>

</ContentPage>
BlogViewModel
using Prism.Navigation;
using SimpleBlog.Models;

namespace SimpleBlog.ViewModels
{
    public class BlogViewModel : ViewModelBase
	{
        public BlogViewModel(INavigationService navigationService)
            : base(navigationService)
        {
               
        }

        private Blog _blogDetail;
        public Blog BlogDetail
        {
            get { return _blogDetail; }
            set { SetProperty(ref _blogDetail, value); }
        }
        public override void OnNavigatedTo(NavigationParameters parameters)
        {
            BlogDetail = (Blog)parameters["Blog"];
            Title = BlogDetail.BlogTitle;
            base.OnNavigatedTo(parameters);
        }
    }
}

To intercept the parameters which are being sent, we need to override the OnNavigatedTo method. This would allow us to obtain the parameters and update our binding object to allow the View to display the information.

Summary

Xamarin Forms is a handy platform for creating mobile applications using the .NET framework. It has the flexibility of building the app once and then it’s shared among other platforms like Android, iOS, and Windows Phone. I also feel that Prism complements Xamarin forms by assisting users with code maintainability, best practices, and ease of use.

For more information, use the following links:

I hope that you’ve found this demonstration helpful and consider giving these tools a try!

See Also:  AWS AppSync with Lambda Data Sources

Comments 2

  1. Hi, this is very good demo of this amazing framework
    But I need to ask a question:
    This prism and xamarin help building cross-platform app, so what is the tool needed to create reports can be previewed with created app, and can be printed
    Appreciate free or open source tool

What Do You Think?