TinyMvvm – The best MVVM library for Xamarin.Forms!?

I have used many different MVVM frameworks/libraries, MvvmLight, Prism, MvvmCross etc. But I have not found any library that I think works great with Xamarin.Forms.

When I created TinyNavigationHelper I had an idea about that I did not needed an MVVM library and that it was enough to have an abstraction for the navigation part, so I could navigate from view models without passing the navigation service from Xamarin.Forms to it. I like to keep any UI frameworks away from my view models, so I do not want to have a dependency on Xamarin.Forms in my view models.

But after a few projects, I realized that I often wrote the same code again, again and again for every new project I started to work with. So I decided to create a library that contained the code I use to rewrite for each and every project, and the result of that is TinyMvvm. TinyMvvm is open source with MIT license and you can find the code on GitHub, https://github.com/TinyStuff/TinyMvvm. On GitHub can you also find the complete documentation including a sample project.

While I liked to use TinyNavigationHelper for navigation I decided to use that library inside of TinyMvvm for handling navigation. One thing that was important for me was that navigation should work well with TabbedPage and MasterDetailPage, I also wanted to be able to have navigation pages in modals. For example, if you are in a TabbedPage with one NavigationPage for each tab, I only want to navigate inside the selected tab. TinyNavigationHelper will handle that for you without the need to write extra code for that.

If you want to read more about navigation, I recommend you to read the blog post I wrote about TinyNavigationHelper, http://danielhindrikes.se/index.php/2017/09/14/tinynavigationhelper-for-xamarin-forms/.

TinyMvvm is created for Xamarin.Forms, but it is architecture in a way that not will lock it to Xamarin.Forms. There is a Xamarin.Forms specific package that contains the UI part of TinyMvvm, but the core package could be used on every platform that supports .NET Standard.

Some people will probably think TinyMvvm probably breaks one or more MVVM rules, but TinyMvvm is created to make me be more productive when building apps with Xamarin.Forms using an MVVM pattern.

Setup TinyMvvm for Xamarin.Forms

There are three things (two if you do not want to use IoC),
the first thing is to configure navigation:

// Option 1:
var navigationHelper = new NavigationHelper(this);
navigationHelper.RegisterView("MainView");
		
// Option 2: Register single views		
var navigationHelper = new FormsNavigationHelper(this);		
navigationHelper.RegisterView("MainView", typeof(MainView));		
		
// Option 3: Register all views (pages) that is inherited from Page		
// The class name will be the key. To use this, you need to add using System.Reflection;		
var asm = typeof(App).GetTypeInfo().Assembly;		
navigationHelper.RegisterViewsInAssembly(asm);

Next step is to setup IoC. TinyMvvm has a resolver that the library uses for resolving types and you can also use it when you need it.

var container = builder.Build();

var autofacResolver = new AutofacResolver(container);

Resolver.SetResolver(autofacResolver);

The last thing you need to do is to call the Initialize method of TinyMvvm.

TinyMvvm.Forms.TinyMvvm.Initialize();

Set MainPage

You can set MainPage in App.xaml.cs (or App.cs if you do not use XAML) if you want, but the recommended way is to use the SetRootViewMethod of the navigationHelper.

NavigationHelper.Current.SetRootView("MyGreatMainView");

ViewModelBase

ViewModelBase is an abstract class that you can use as a base for your view models, it is implementing the INotifyPropertyChanged interface and has properties for IsBusy, IsNotBusy and Navigation etc.

Lifecycle overrides

In a view model that inherits from ViewModelBase, you can override three methods for handling the lifecycle for a view. The reason that I built this was that it tends that I often created methods for OnAppearing in the view model and called them from the OnAppearing from the view and I think it would be nice to have this in the view model without having to write code in the view every time.

Initialize

This will run only after that a ViewModel is created. It is recommended that you are using this method for loading data for the ViewModel. If you are passing parameters during navigation the parameter will be available here, use the NavigationParameter property to access the parameter. NavigationParameter cannot be used in the constructor for the view model.

OnAppearing

This method is called when a user navigates to a view, the first time or when a user returning to a view. I use to use this method for refreshing data. If I have events I use to subscribe to them here, so they will be restored when the user returning to the view while I use to unsubscribe from them when the user leaving the view.

OnDisappearing

This method will run when the user leaving a view. I use to use this for unsubscribing to events.

public class MyViewModel : ViewModelBase
{
     public override async Task Initialize()
     {
          var id = (int)NavigationParameter;
     }

     public override async Task OnAppearing()
     {
     }

     public override async Task OnDisappearing()
     {
     }
}

Navigation

You can access the NavigationHelper with the Navigation property in ViewModelBase, but you also have a NavigateTo command (implemented by Johan Karlsson) that makes it possible to trigger navigation from your XAML without adding anything to your view model. The only thing you have to do is to send the view key as a command parameter.


public ICommand GoToView => new TinyCommand(async() => await Navigation.NavigateToAsync("TheKeyForTheGreatViewYouWantToNavigateTo"));

public ICommand GoBack => new TinyCommand(async() => await Navigation.BackAsync());

TinyCommand

While we do not want to have references to Xamarin.Forms in our ViewModels TinyMvvm has an own ICommand implementation, TinyCommand.

ViewBase

With TinyMvvm you can use ViewBase as your base class instead of ContentPage. ViewBase is a ContentPage but it added some extra nice features. There are one ViewBase and one ViewBase where T : INotifyPropertyChanged. The generic one makes it possible to set BindingContext from XAML. If you want Initialize, OnAppearing and OnDisappering in your view models to work you have to some of the ViewBase variants.


Feedback and/or bugs

If you have feedback or find a bug in TinyMvvm, please create an issue on GitHub, https://github.com/TinyStuff/TinyMvvm/issues.

Contribute

You are very welcome to contribute to TinyMvvm. If you want to add a new feature we would like if you create an issue first so we can discuss the feature before you spend the time to implement it.

  6/26/2018 - 11:38 AM