Search
Filters
Blog options
Close

Setting up your first ReactiveUI Project with Xamarin Forms

Setting up your first ReactiveUI Project with  Xamarin Forms

In this tutorial we go through the process of installing and setting up ReactiveUI 7 in Xamarin using the Model-View-View-Model pattern. Here, we'll take a high level look at all of the moving pieces we need in order to end up with an app that binds using ReactiveUI.

Installing ReactiveUI

We’ll begin by opening Visual Studio (or Xamarin studio) for mac. We’ll select `File->New Solution` and we’ll select Forms App. Click Next. Choose a name, we’ll target both Android and iOS, choose portable class library and I personally write my interfaces using C# but you can use XAML if that’s what you are comfortable with. We’ll move on to the next dialog and if we’re happy with were Visual Studio is saving our project, we’ll click create.

Once Visual Studio has finished loading our project we’ll go ahead and add our ReactiveUI packages.

Expand your Xamarin forms project and right click on packages and select `Add Packages…` Once the package manager dialog appears, search for RectiveUI, select the version you want to work with and click Add Packages. Accept the subsequent agreements and your packages should install without a problem. Next, go ahead and install the reactiveui-xamforms package. 

Once complete, double check that your packages look like this:

Noticed that the package manager has automatically added the Rx and Splat dependences along with reactiveui and reactiveui-core.

Next, we’ll go ahead and add ReactiveUI to both our .Droid and .iOS projects as well. These steps are the same as with the forms project.

Just make sure that all of your package versions are exactly the same.

ReactiveUI Base Classes

Now that we have ReactiveUI installed we’ll set up our project using the MVVM pattern.

We’ll begin by adding two folders to our Xamarin Forms application. We’ll create a folder for our ContentPages, which we’ll call UserInterfaces and one for our ViewModels which we’ll call ViewModels. Once complete, your solution should look something like this.

Next, we’ll add a pair of base classes. While this step isn’t necessary to use ReactiveUI, it does enforce a predictable pattern across our documents making them easier to work with over time.

We’ll start by right clicking on our ViewModels and we’ll select add file. We’ll create a new C# file which we’ll name ViewModelBase. Next we’ll add the following code.

// 1
public abstract class ViewModelBase<T> : ReactiveObject, IDisposable where T : ReactiveObject, IDisposable 
{
    // 2
    protected readonly Lazy ViewModelBindings = new Lazy(() => new CompositeDisposable());
    // 3
    public bool IsDisposed { get; private set; }
    // 4
    protected abstract void RegisterObservables();
    // 5
    protected ViewModelBase()
    {
        RegisterObservables();
    }
    // 6
    #region IDisposable implementation
    public void Dispose()
    {
        if (!IsDisposed)
        {
            IsDisposed = true;
            Dispose(true);
            GC.SuppressFinalize(true);
        }
    }

    protected virtual void Dispose(bool disposing)
    {
        if (disposing)

        if (ViewModelBindings != null)
        {
            ViewModelBindings.Value.Dispose();
        }
    }

    #endregion
}

This is a minimal version of a ViewModelBase class implementation that I learned from the mobile development experts at Eight Bot. This version, of course, is drastically stripped down compared to what one might use in production. But it will get us up and running for this exercise.

Let's take a high level look at what's going on here.

  1. We have an abstract class named ViewModelBase that offered a generic parameter. In ReactiveUI, all view model base classes must inherit from ReactiveObject, we are also implementing IDisposable. Finally, we're explicitly stating that our generic `T` parameter must implement both ReactiveObject and IDisposable.
  2. We’ve created a Lazy CompositeDisposable named ViewModelBindings. We’ll use this property to collect our ViewModels disposable subscriptions which get cleared out when our pages Dispose override method gets called. To learn more about CompositeDisposable check out the Introduction to Rx page on Disposables.
  3. We’re employing a boolean flag named IsDisposed to keep track of whether our objects have been disposed. This will keep us safe from disposing of an object more than once.
  4. RegisterObservables is an abstract method that we'll use to register our observables in our view model.
  5. Our class constructor which, in this simple example, simply calls our RegisterObservables method.
  6. Finally we take care of our disposables. This should be familiar to those who have spent any time using .Net. You can learn more about IDisposable here[3]

That does it for our ViewModelBase class. Once again, this is a simple version of what one might use in production but it is by no means production ready. Let’s go ahead and wire up a ContentPage base class using ReactiveUI.

Right click on your UserInterfaces folder and add a new C# file named ContentPageBase. Next, we’ll add the following code to out new file.

// 1
public abstract class ContentPageBase<T> : ReactiveContentPage where TViewModel : ViewModelBase 
{   
    // 2
    protected Lazy ControlBindings = new Lazy(() => new CompositeDisposable()); 

    // 3 
    protected abstract void SetupUserInterface();
    protected abstract void BindControls();

    // 4
    protected ContentPageBase() : base()
    {   
        SetupUserInterface(); 
        BindControls();  
    }

    // 5
    protected override void OnDisappearing()
    {
        base.OnDisappearing();  
        UnbindControls(); 
    }  

    protected void UnbindControls()
    {  
        if (ControlBindings == null) return; 
        ControlBindings.Value.Clear();
    } 
}

As with our ViewModelBase, this ContentPageBase is a simplified example of what you might use in production.

Let’s break this down line by line.

  1. First and foremost, we are inheriting from ReactiveUI’s generic ReactiveContentPage class, which takes a generic type which is of type ViewModelBase.
  2. Here we are defining a lazy CompositeDisposable. We’ll use this property to collect our disposable subscriptions which get cleared out when our pages OnDisappearing override method gets called.
  3. We we are defining two abstract methods. One that will run our user interface code, and another that will bind our user interface controls to our View Model properties.
  4. Here we have our constructor, which calls SetupUserInterface followed by BindControls
  5. Next we call Xamarin Forms’ OnDisappearing method where we’ll remove our ControlBindings.

ReactiveUI in Action

Now we have everything we need to wire up a simple interface. We’ll begin by adding a new class which we’ll name `Dashboard.cs` to our ViewModels folder. Once our document has loaded we’ll make sure that our namespace to reflect our folder hierarchy to avoid collisions.

namespace YourAppName.ViewModels

We’ll inherit from our newly created ViewModelBase class and simply pass our Dashboard class type in as our type specifier. At this point Visual Studio will require that we implement our abstract base class, which is what we’ll do.

Before we move on, I want to point out that the goal of this exercise it for you to get up and running with ReactiveUI and MVVM. So I’ll forgo any in-depth explanation of the moving pieces you’re about to see. If you have any questions feel free to leave them in the comments section below.

Let’s go ahead and add the rest of our Dashboard class now.

public class Dashboard : ViewModelBase
{ 
    // 1
    string _statusMessage;

    [DataMember]
    public string StatusMessage
    {
        get { return _statusMessage; }
        private set { this.RaiseAndSetIfChanged(ref _statusMessage, value); }
    }

    ImageSource _currentImage;

    [DataMember]
    public ImageSource CurrentImage
    {
        get { return _currentImage; }
        set { this.RaiseAndSetIfChanged(ref _currentImage, value); }
    }

    [DataMember]
    public List ImageList { get; set; } = new List();
 
    [DataMember]
    public string Title
    {
        get { return "My Dashboard"; }
    }
    // 2
    public ReactiveCommand<Unit, Unit> InitializeCommand { get; private set; } 

    // 3
    protected override void RegisterObservables()
    {
        // 4
	InitializeCommand = ReactiveCommand.CreateFromTask(async _ => 
	{
	    // initialization logic goes here 
	    StatusMessage = "Initializing";

	    // maybe we're getting images from a server 
	    await Task.Delay(1000); // but we should really use Task.Delay in our apps right?

	    StatusMessage = "Downloading";

	    // simulate a lengthy server response
	    await Task.Delay(3000); 

	    StatusMessage = "Go-Go Random Logos!";

	    ImageList.Add("xamagon.png");
	    ImageList.Add("eightbot.png");
	    ImageList.Add("reactivelogo.png");
	    ImageList.Add("codebeaulieu.png");
	    ImageList.Add("Rx_Logo_512.png");

	    await Task.Delay(1000);
	    await Task.FromResult(Unit.Default);

}).DisposeWith(ViewModelBindings.Value); // 5 Observable .Interval(TimeSpan.FromMilliseconds(500)) .ObserveOn(RxApp.MainThreadScheduler) .Select(_ => { if (ImageList.Count == 0) return ImageSource.FromFile("reactivelogo.png"); Random random = new Random(); int number = random.Next(0, ImageList.Count); return ImageSource.FromFile(ImageList[number]); }).BindTo(this, x => x.CurrentImage); } }

We’ll take a high level look at whats going on but we’ll spare the detail.

  1. We’ve included several properties that we’ll bind to in our Dashboard ContentPage.
  2. We’re including a status message which is of type string, current image which is a Xamarin Forms ImageSource, a List of strings that will hold a list of image names and title which is of type string.
  3. We’re including a ReactiveCommand which we’ll bind to in our ContentPage later.
  4. Next we have our RegisterObservables method which, if you recall from our base class implementation, gets called from our constructor.
  5. Here we have our ReactiveCommand implementation. When our command gets fired from our ContentPage, this is the logic that will execute.
  6. Finally, we have a Reactive observable that fires every have second and binds a random image to our CurrentImage property.
Important: In order for your application to run, you’ll need to add images to both your iOS and Droid projects respectful resource folders. If you are at a shortage of images, you can use the ones that I’ve included in this project by downloading them from my example project here.[4]

Alright, we’re almost there! Let’s finish up by adding a content page to our app. We’ll right click on our UserInterfaces folder and add another file named Dashboard.cs. Hopefully you remembered to change your namespace earlier or you’ll be sure to confuse the compiler.

The first thing we’ll do is inherit from our ContentPageBase and then we’ll pass in our view model dashboard type. The rest of the code for this demo, goes something like this:

public class Dashboard : ContentPageBase
{
    // 1
    Image _images;

    Label _status;

    //2
    public Dashboard()
    {
        ViewModel = new ViewModels.Dashboard(); 
    }

    //3
    protected override void SetupUserInterface()
    { 
        _status = new Label
        { 
            FontSize = 20,
	    FontFamily = Device.OnPlatform("AvenirNext-Medium", "Roboto", "Verdana"),
	    HorizontalTextAlignment = TextAlignment.Center,
	    VerticalTextAlignment = TextAlignment.Center,
	    HorizontalOptions = LayoutOptions.CenterAndExpand,
	    VerticalOptions = LayoutOptions.Center,
	    Margin = new Thickness(0,40,0,0)
        };

        _images = new Image {
	    HorizontalOptions = LayoutOptions.FillAndExpand,
	    VerticalOptions = LayoutOptions.FillAndExpand,
	    Aspect = Aspect.AspectFit, 
	    HeightRequest = 350 
        };

	Content = new StackLayout 
	{
	    HorizontalOptions = LayoutOptions.FillAndExpand,
	    VerticalOptions = LayoutOptions.FillAndExpand,
	    Padding = 20,
	    Children = { 
                _status,
		_images
	    }
        };
    }

    //4
    protected override void BindControls()
    {
        this.OneWayBind(ViewModel, vm => vm.Title, c => c.Title)
	    .DisposeWith(ControlBindings.Value);

	this.Bind(ViewModel, x => x.StatusMessage, c => c._status.Text)
            .DisposeWith(ControlBindings.Value);

        this.WhenAnyValue(x => x.ViewModel.CurrentImage)
            .BindTo(this, x => x._images.Source)
	    .DisposeWith(ControlBindings.Value);
        
        this.WhenAnyValue(x => x.ViewModel)
            .Where(x => x != null)
            .InvokeCommand(this, x => x.ViewModel.InitializeCommand)
            .DisposeWith(ControlBindings.Value);
    } 
}

Since the goal is to demonstrate the pattern, we’ll take a high level look at the rest of the implementation.

  1. Here we have our user interface controls. We’ll be binding to these in a moment.
  2. Here we have our class constructor. We’re setting our ViewModel equal to our ViewModels.Dashboard file. ViewModel belongs to the ReactiveUI framework.
  3. Next, we’re calling our InitializeCommand on our freshly set view model and calling execute. This will execute our logic in our InitializeCommand implementation.
    User interface setup, nothing interesting here.
  4. And here is where the magic happens… We’re using three different binding statements to bind our interface controls to observables in our view model.

So, your code should be complaining right now since DisposeWith doesn’t actually exist in ReactiveUI! This is an extension method provided by Eight Bot in their public GitHub repository on Reactive-Extension, which you can find here.

Create a new folder in your application named Extensions and add a new class named IObservableExtensions. Add the following code.

/*
    This extension was taken from Eight Bot's Reactive-Exampes repository with permission.
    url: https://github.com/TheEightBot/Reactive-Examples/blob/master/ReactiveExtensionExamples/Extensions/IObservableExtensions.cs
    author: Mike Stonis
    website: http://www.eightbot.com/
*/
public static class IObservableExtensions
{
    public static TDisposable DisposeWith(this TDisposable observable, CompositeDisposable disposables) where TDisposable : class, IDisposable
    {
        if (observable != null)
            disposables.Add(observable);

	return observable;
    }
}

Thanks to Mike Stonis for sharing gems like this.

And with that, we are ready to run our application.

ReactiveUI CodeBeaulieu

 

Download project files from GitHub