Daniel Hindrikes
Developer and architect with focus on mobile- and cloud solutions!
Developer and architect with focus on mobile- and cloud solutions!
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.
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();
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 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.
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.
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.
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.
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()
{
}
}
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());
While we do not want to have references to Xamarin.Forms in our ViewModels TinyMvvm has an own ICommand implementation, TinyCommand.
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
If you have feedback or find a bug in TinyMvvm, please create an issue on GitHub, https://github.com/TinyStuff/TinyMvvm/issues.
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.