If you guys have not use this combination I strongly suggest to give it a try. Prism handles navigation like a boss, ReactiveUI makes your code readable that you will comeback 6 months from today and you will still be able to pick it up fairly quickly (that is not the only reason of course but one of the most appealing for me) and Xamarin Forms (no need for introductions here).
If you have never used Prism or ReactiveUI I recommend:
Prism in Xamarin Forms Step by Step by Xamgirl.
And
You, I, and ReactiveUI by Kent Boogaart.
Now, How do we use them together?
So are we using two MVVM frameworks together? Well yes, but we are taking the best part of both.
I am not going to start a debate on MVVM frameworks choices, selection, advantages or disadvantages. I am simply stating my preferences.
For this sample I took the Contoso Cookbook classic Microsoft sample recipe app from https://github.com/PrismLibrary/Prism-Samples-Forms. I updated it to Prism 7.2. Xamarin Forms 4.2 and RxUI 9.19.5. Then added login and search for the recipes.
The idea is simple, as you can see in my ViewModelBase:
using Prism.Mvvm; using Prism.Navigation; using Prism.Services; using ReactiveUI; using System; using System.Reactive; using System.Reactive.Disposables; namespace ContosoCookbook.ViewModels { public class ViewModelBase : ReactiveObject, INavigationAware, IConfirmNavigation, IDestructible, IInitialize { public ViewModelBase() { } public virtual void OnNavigatedFrom(INavigationParameters parameters) { } public virtual void OnNavigatedTo(INavigationParameters parameters) { } public virtual void Initialize(INavigationParameters parameters) { } private string _Title; public string Title { get { return _Title; } set { this.RaiseAndSetIfChanged(ref _Title, value); } } private bool _IsBusy; public bool IsBusy { get { return _IsBusy; } set { this.RaiseAndSetIfChanged(ref _IsBusy, value); } } public bool IsNotBusy { get { return !IsBusy; } } protected void BindBusy(IReactiveCommand command) { command.IsExecuting.Subscribe( x => this.IsBusy = x, _ => this.IsBusy = false, () => this.IsBusy = false ); ; } public bool CanNavigate(INavigationParameters parameters) { return true; } public void Destroy() { } } }
My ViewModelBase inherits from ReactiveObject and implements INavigationAware and a few more interface from the Prism Library.
Let’s see the RecipeViewModel implementation:
using System; using ContosoCookbook.Business; using Prism.Navigation; using ReactiveUI; namespace ContosoCookbook.ViewModels { public class RecipePageViewModel : ViewModelBase { private Recipe _recipe; public Recipe Recipe { get => _recipe; set => this.RaiseAndSetIfChanged(ref _recipe, value); } public RecipePageViewModel() { } public override void Initialize(INavigationParameters parameters) { if (parameters.ContainsKey("recipe")) Recipe = parameters.GetValue<Recipe>("recipe"); } } }
As you can see we are using the Initialize to handle navigation and the RaiseAndSetIfChanged from ReactiveUI.
Having all of this in place now we can do things like validation using WhenAnyValue and searching (we can not omit the most iconic sample like shown below).
The reason for this post was a talk with Andres Pineda where we realized the ReactiveUI samples for Xamarin Forms were missing a really simple Prism + ReactiveUI love.
I kept it as simple as possible. Hope you guys find it useful.
Get the complete source code here.