Setup Xamarin Forms with Reactive UI

Setup Xamarin Forms with Reactive UIXamarin Forms is versatile enough on its own. Combine it with Reactive UI and you get the most elegant and modular apps on any mobile or desktop platform.

I started writing Android apps using Xamarin Forms a couple of months ago and fell in love with it immediately. Also, by having an MVVM background, I decided that it would be a good approach this time too. Therefore I choose to work with Reactive UI, a MVVM framework that allows you to use the Reactive Extensions for .NET in Xamarin Forms. In my opinion this is a game changer and opens up a totally different and exciting approach.

I won’t dwell into the details of MVVM or Reactive Programming, you will find links in the last paragraph of this article. Consider them as concepts that will make my tutorial more easy to follow. However, fully grasping them, as I said, is not a requirement.

While you can target multiple platforms with Xamarin Forms, starting with Android, iOS, different flavors of Windows Phone and Windows UWP, my main focus will be Android. This is just for keeping things simple. In addition this is a platform under which Xamarin Forms behaves well.

The demo app this tutorial aims to create will be a simple list of persons with the possibility of viewing the details of a certain person. This will cover the MVVM basics of Reactive UI and how it’s navigation works.

As always, the full source code for this tutorial is available at https://github.com/levifuksz/xamarin-reactiveui

Before You Begin

I tried to keep the things simple and aimed this tutorial towards beginners, however some basic knowledge is required. I assume you know a bit of C# and that you get the idea behind XAML user interfaces. Prior Android development experience is not required because you can just start writing C# code in Xamarin Forms. No Java knowledge is required.

I also assume that you have Visual Studio installed together with the Xamarin Platform. You can fetch Visual Studio 2017 Community version for free from the Microsoft website.
https://www.visualstudio.com/

Make sure that when you are installing Visual Studio 2017 you also install the Xamarin Platform as shown in the image below.

The Xamarin Platform also comes as a separate download. This is in case you already have Visual Studio installed. Grab it from their website at https://www.xamarin.com/platform

Setting up the Xamarin Forms Project

Open Visual Studio and go to File > New > Project. You can also press Ctrl + Shift + N key combination to achieve the same result.

In the new window, on the left side tree, navigate to Installed > Templates > Visual C# > Cross-Platform and choose Cross Platform App (Xamarin Forms or Native). Also don’t forget to choose a fitting name for the project. Proceed by clicking OK. See the image below.

New Xamarin Forms Project

In the next dialog please make sure to choose Portable Class Library under Code Sharing Strategy. Leave everything else unchanged like in the image. Finally click OK.

Depending on what other development platforms you have installed some additional dialogs may appear during project creation. It is safe to ignore anything iOS, Windows Phone or Universal Windows Platform related. Leave these settings unchanged because our main focus will be Android.

Going Reactive

After the project creation completed we can finally add the Reactive UI NuGet package to the solution. I know I just assumed that you are familiar with NuGet Package Manager but it’s not rocket science. It is just a tool for adding packages, or libraries if you prefer this naming, to your projects. We will use this tool for adding Reactive UI.

While there is a “visual” way of adding NuGet packages to our projects, I choose the “console” way in order to keep this article shorter. Therefore, go to Tools > NuGet Package Manager > Package Manager Console. In the new console window that appeared at the bottom of the Visual Studio window type:

Get-Project -All | Install-Package reactiveui-xamforms

This command will enumerate all projects in the solution and install the “reactiveui-xamforms” NuGet package into them.

Creating the Data

All files that we add or edit in this article will be located in the Portable project. We won’t touch the Android one. Please pay attention to this!

Before we are able to display the persons for our example we need to model them. Also the data needs to come from somewhere. In real life scenarios the data will come from a service but in our case we will just hard-code it.

Start by adding a new class called Person to the Portable project. A person will have a name, a description, a website and a Twitter handle. Start adding these properties to the class. In the end your class should look like the code below.

public class Person
{
    public string Name { get; set; }        
    public string Description { get; set; }
    public string Website { get; set; }
    public string TwitterHandle { get; set; }
}

The list of Persons as I mentioned will be hard-coded for the sake of simplicity. Let’s create a PersonsProvider class for this purpose. This class should have list of persons like the one below. Don’t forget to add more, be inventive.

private List<Person> _persons = new List<Person>()
{   
	new Person()
	{
		Name = "Levente Fuksz",
		Description = "Coder and InfoSec Enthusiast",
		TwitterHandle = "@levifuksz",
		Website = "https://blog.iamlevi.net"
	}
};

Finally, the PersonsProvider should have a method to return the above list. It should also support filtering by person’s name. See below.

public async Task<List<Person>> GetPersons(string search)
{
	// Simulate some loading time
	return await Task.Delay(800)
		.ContinueWith((task) =>
		{
			return string.IsNullOrEmpty(search) ?
				_persons :
				_persons.Where(p => p.Name.IndexOf(search, StringComparison.OrdinalIgnoreCase) != -1).ToList();
		});
}

The full PersonsProvider can be found at PersonsProvider.cs

The Main Page View Model

Code for this file can be found at MainPageViewModel.cs

Let’s add the view model for the Main Page. Do so by adding a class called MainPageViewModel. This class should inherit ReactiveObject and implement IRoutableViewModel. By inheriting ReactiveObject we can access a set of reactive helper methods while implementing IRoutableViewModel makes navigating to this view model possible the Reactive UI way.

Properties

The IRoutableViewModel declares two properties we need to implement. The first one is the “title” of the view model while the other one is the current screen object. We can use the screen object for navigation purposes. We will get to this later in the Navigation paragraph. For now just add these properties.

public string UrlPathSegment => "Persons";

public IScreen HostScreen { get; set; }

Add a property with a backing field to hold the filter text used to search for persons.

private string _searchTerm;
public string SearchTerm
{
    get { return _searchTerm; }
    set { this.RaiseAndSetIfChanged(ref _searchTerm, value); }
}

The RaiseAndSetIfChanged triggers a property changed event and notifies subscribers. This happens only whenever the value of the search term changed. Setting the same value twice wont trigger this event.

The search will be done by a command called Search

public ReactiveCommand<string, List<Person>> Search { get; set; }

This command takes a string as a parameter, in our case the search term, and returns a list of persons.

We need two properties to handle output from the Search command. The first one is an ObservableAsPropertyHelper that helps view models implement “output properties”. It subscribes to an IObservable and handles the changes notification. The second property is just a list of persons. This is the “output property” that is tied to the ObservableAsPropertyHelper.

private ObservableAsPropertyHelper<List<Person>> _searchResults;

public List<Person> Persons => _searchResults.Value;

We also need a property with a backing field for the currently selected person.

private Person _selectedPerson;

public Person SelectedPerson
{
    get { return _selectedPerson; }
    set { this.RaiseAndSetIfChanged(ref _selectedPerson, value); }
}

Finally we need something that tells us when the list of persons is loading.

private ObservableAsPropertyHelper<bool> _isSearching;

public bool IsSearching => _isSearching.Value;

Logic

First thing first, we have a HostScreen property that needs a value. Time to introduce the service locator that comes with Reactive UI. If you are not familiar with the “Service Locator” concept I have a link to an article at the end of this page. This pattern registers “services”. Code that needs those services can request them. Getting an IScreen instance for the HostScreen property is done as below.

this.HostScreen = Locator.Current.GetService<IScreen>();

Next we define what the Search command does.

this.Search = ReactiveCommand.CreateFromTask<string, List<Person>>(async (search) =>
{
    var personsProvider = new PersonsProvider();
    return await personsProvider.GetPersons(search);
});

The Search command is triggered when SearchTerm property is changed. This is achieved using the WhenAnyValue method of the ReactiveObject we inherit. We also throttle the execution of this command for performance purposes.

this.WhenAnyValue(vm => vm.SearchTerm)
    .Throttle(TimeSpan.FromMilliseconds(500), RxApp.MainThreadScheduler)
    .Select(s => s?.Trim())
    .DistinctUntilChanged()
    .InvokeCommand(this.Search);

The command execution status and the result are assigned to the corresponding properties.

this._isSearching = this.Search.IsExecuting
    .ToProperty(this, vm => vm.IsSearching, false);

_searchResults = this.Search.ToProperty(this, vm => vm.Persons, new List<Person>());

The last thing left to do is to trigger a search with an empty search term to list all persons.

this.Search.Execute(string.Empty).Subscribe();

Please note that we need to call the Subscribe method in this case to make the asynchronous call synchronous. Normally we would use the await keyword but we can’t make the constructor asynchronous too.

The Main Page View

Xamarin Forms uses XAML to describe the user interface. The UI for the main page consists of an Entry control that will be used to search persons and a ListView to display them. Both controls are children of a StackLayout control that makes them appear one under the other.

The code for the main page can be viewed at MainPage.xaml. I will describe it below.

As you can see in the code, the Text property of the Entry is bound to the SearchTerm property of the view model.

The ListView is bound to three properties. First we bind the ItemSource to Persons and then the SelectedItem to the view model’s SelectedPerson. Also the IsRefreshing property, used to display a loading indicator, is bound to IsSearching.

Moving along, we need to do some work in the code behind. You can access the code behind in the Solution Explorer under the MainPage.xaml file. See below

Solution Explorer

Here is the full code behind: MainPage.xaml.cs

First we need implement the IViewFor interface. This is a generic one and tells Reactive UI that the MainPage is a view for the MainPageViewModel view model.

public partial class MainPage : ContentPage, IViewFor<MainPageViewModel>

In order to implement this interface we need to declare the ViewModel property. The best way to do this is to make it a bindable property. You can read more about them in a link at the end.

BindableProperty ViewModelPoperty = BindableProperty.Create(nameof(ViewModel), typeof(MainPageViewModel), typeof(MainPage));

public MainPageViewModel ViewModel
{
    get { return (MainPageViewModel)GetValue(ViewModelPoperty); }
    set { SetValue(ViewModelPoperty, value); }
}

object IViewFor.ViewModel
{
    get { return ViewModel; }
    set { ViewModel = (MainPageViewModel)value; }
}

Finally, because Xamarin Forms uses the BindingContext property to supply data to bindings in the XAML we need to bind the ViewModel property to it. We do this in the constructor of the page.

this.WhenAnyValue(v => v.ViewModel).BindTo(this, v => v.BindingContext);

With this last line of code our main page is done but we still need to work in order to make it run.

The Details View Model

This view model is a simple one. Besides the properties required by the IRoutableViewModel implementation it only has a single property. This holds the currently selected person and it is set in the constructor from a parameter. All you have to do is to add a class called DetailsPageViewModel and paste in the code bellow.

public class DetailsPageViewModel : ReactiveObject, IRoutableViewModel
{
    public Person CurrentPerson { get; private set; }

    public string UrlPathSegment => $"{CurrentPerson.Name} - Details";
    public IScreen HostScreen { get; set; }

    public DetailsPageViewModel(Person currentPerson)
    {
        this.CurrentPerson = currentPerson;
        this.HostScreen = Locator.Current.GetService<IScreen>();
    }
}

The same code is on GitHub too at DetailsPageViewModel.cs.

The Details View

I won’t go in too much into the XAML of the DetailsPage. You create it from the menu by going to Project > Add New Item … or by pressing Ctrl+Shift+A. Just make sure you are adding a Forms Content Page Xaml like in the picture.

Xamarin Forms Content Page

The full XAML for this page is available at DetailsPage.xaml.
It only contains a TableView that displays the properties of a person.

Finally, the code behind for this page follows the same pattern as the main page code behind. Grab it from DetailsPage.xaml.cs.

Navigation

Now that we have both the main page and the details one it is time to link them. We want to view the details of a person every time we choose one from the list. Let’s do this the Reactive way.

Go into the MainPageViewModel and add the following command:

public ReactiveCommand ShowDetails { get; set; }

This will be used to navigate to the details page.

Also paste the following code at the end of the constructor.

this.ShowDetails = ReactiveCommand.CreateFromTask<Person>(async (person) =>
{
    await this.HostScreen.Router.Navigate.Execute(new DetailsPageViewModel(person));
    this.SelectedPerson = null;
});

Executing this command will do the navigation using the Navigate command of the IScreen‘s Router. Please note that in Reactive UI we navigate to view models not views. After the navigation we clear the SelectedPerson so it can be selected again.

The best way to trigger navigation is to subscribe to the change of the SelectedPerson property. Add more code at the end of the constructor.

this.WhenAnyValue(vm => vm.SelectedPerson)
    .Where(p => p != null)
    .InvokeCommand(this.ShowDetails);

Fire it up

In order to be able to start the application we need to do some setup work. This means declaring the IScreen instance, register some services and link views and view models together. Begin by opening the code behind for the App.xaml.

View the full code at App.xaml.cs.

Make the App class implement the IScreen interface and add a RoutingState property called Router.

public partial class App : Application, IScreen
{
    public RoutingState Router { get; set; }
...

Move into the constructor and instantiate the Router.

this.Router = new RoutingState();

The next step is to register services, in our case only the IScreen instance. Next we link views to view models.

Locator.CurrentMutable.RegisterConstant(this, typeof(IScreen));

Locator.CurrentMutable.Register(() => new MainPage(), typeof(IViewFor<MainPageViewModel>));
Locator.CurrentMutable.Register(() => new DetailsPage(), typeof(IViewFor<DetailsPageViewModel>)); 

We then navigate the Reactive UI way to the main page.

this.Router.Navigate.Execute(new MainPageViewModel());

The only step left, related to navigation, is to make the applications main page be a RoutedViewHost. This is the page type used by Reactive UI to handle navigation from the RoutingState.

MainPage = new RoutedViewHost();

We are done. This concludes our Xamarin Forms tutorial. Fire up the application and check your work.

Further Reading

A good article about the MVVM pattern can be found at
Model-View-ViewModel (MVVM) Explained

You can find the full Reactive UI documentation on GitBook but be warned, it is still work in progress.
ReactiveUI Documentation

If you feel you want to go deeper and explore Reactive Programming there is an excellent article for that too.
The introduction to Reactive Programming you’ve been missing

Read more about Shared Projects versus Portable Class Libraries at
Sharing Code Options

For those that have no clue about what a Service Locator pattern is read this.
Service Locator Design Pattern

The Xamarin Forms bindable property documentation can be found at:
Bindable Properties

Finally, you can look over another article written by me, covering a bit of Xamarin Forms.
Control a Raspberry Pi with Android Over Bluetooth

T3ZlciBBbmQgT3V0IQ==

Recent Posts

Be First to Comment

Leave a Reply

This site uses Akismet to reduce spam. Learn how your comment data is processed.