Daniel Hindrikes
Developer and architect with focus on mobile- and cloud solutions!
Developer and architect with focus on mobile- and cloud solutions!
TinyMvvm is a library that I created a couple of years ago. The idea was to build a small (tiny) MVVM library that made me more productive. I first released TinyNavigationHelper that helped med to abstract the Xamarin.Forms navigation, because I do not want my ViewModels to have references to Xamarin.Forms.
Last time I updated TinyMvvm was about one and a half year ago, the reason I have not updated it since then is that it has been stable and worked very well for me in multiple apps I have worked with for multiple clients.
When Xamarin.Forms Shell was released I started to work with some improvements to make TinyMvvm work with Xamarin.Forms Shell. But I never finished them, because the current version worked very well together with Shell. The only thing not supported was URL navigation.
But in the current app, I work with I had a use case where URL navigation would be very nice to use. Of course, I could have used it without using the navigation in TinyMvmm. But there are some great features of TinyMvvm that I missed then. For example to get navigation parameters in the ViewModel without having to pass them manually from the view and if I wanted to navigate from the ViewModel I had to add references to Xamarin.Forms inside of them.
There is a couple of new stuff added to TinyMvvm in this release.
If you want to use URL navigation together with TinyMvvm you have to use the ShellNavigtionHelper. ShellNavigationHelper is a subclass of FormsNavigationHelper.
var navigationHelper = new TinyNavigationHelper.Forms.ShellNavigationHelper();
navigationHelper.RegisterViewsInAssembly(appAssembly);
navigationHelper.RegisterView("MainView", typeof(MainView));
The method that is supporting URL navigation is the NavigateTo(string key) method. All other methods of INavigationHelper will use traditional Xamarin.Forms NavigationService. To NavigateTo you can either specify a URL or a key to a view. If it got a key that you have registered as in the code about it will use the traditional NavigationService, otherwise, it will use Shell navigation with URL.
await NavigationHelper.Current.NavigateTo("//home/messages?id=1");
If you are in a ViewModel with ViewModelBase as parent you can use the Navigation property of of the ViewModelBase,
await Navigation.NavigateTo("//home/messages?id=1");
With URL navigation you can pass query parameters. With TinyMvvm you can access them from the ViewModel via the QueryParameters property of ViewModelBase. QueryParameters is of type Dictionary<string, string>.
public override async Task Initialize()
{
await base.Initialize();
var id = QueryParameters["id"];
}
In TinyMvvm 1.x there was a dependency on TinyNavigationHelper, in 2.0 is TinyNavigationHelper added as a submodule and compiled into the same assembly as TinyMvvm. This reduces the amount of referenced assemblies that Xamarin.Forms have to search for custom renderers in.
The constructor to FormsNavigationHelper has changed. You can not pass an instance of Xamarin.Forms.Application anymore, the reason is that it not is necessary to provide the navigation helper with it.
The BeginInvokeOnMainThread future of ViewModelBase has been marked as obsolete, the recommendation is to use Xamarin.Essentials.MainThread.BeginInvokeOnMainThread instead.
Here are some of the basics of TinyMvvm, you will find the full docs and a sample project here, https://github.com/TinyStuff/TinyMvvm.
TinyMvvm.Forms.TinyMvvm.Initialize();
Features (or drawbacks) of the ViewBase
The view should inherit from ViewBase<T>
where T
is the ViewModel. The ViewModel can be any class that has ViewModelBase
as the base class.
ViewBase<T>
itself inherits from Xamarin.Forms.ContentPage
and can be treated by Xamarin Forms as any page.
If you decide to use ViewModelBase
as the base class for your view model and at the same time have the IoC resolver enabled, the view will automatically create the view model for you when the view is created. Hence no need to inject the view model in the constructor and assign it manually. Feature or not, you decide.
An example of a typical page in TinyMvvm would look like this:
<tinymvvm:ViewBase x:TypeArguments="viewmodels:MainViewModel"
xmlns="http://xamarin.com/schemas/2014/forms"
xmlns:viewmodels="clr-namespace:TinyMvvm.Forms.Sample.ViewModels;assembly=TinyMvvm.Forms.Samples"
xmlns:tinymvvm="clr-namespace:TinyMvvm.Forms;assembly=TinyMvvm.Forms"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
x:Class="TinyMvvm.Forms.Sample.Views.MainView">
</tinymvvm:ViewBase>
What you need to do is:
tinymvvm:ViewBase
### ViewModelBase
TinyMvvm also defines a base class for the view model called `ViewModelBase`.
Features of the ViewModelBase
* Wraps navigation for you through the INavigation interface (Implemented in TinyNavigation)
* Implements INotifyPropertyChanged for you
* Propagates life cycle events to the view (Initialize, OnAppearing, OnDisapparing)
### IoC
Tiny Mvvm is not bound to any specific IoC provider. There is a provider for Autofac that you can install with the "TinyMvvm.Autofac" package.
Install-Package TinyMvvm.Autofac
TinyMvvm has a Resolver in its core project. To use it you need to add on a provider to it that implements the IResolver interface, for example, our Autofac provider.
```csharp
var container = builder.Build();
var resolver = new AutofacResolver(container);
Resolver.SetResolver(resolver);
var navigationHelper = Resolver.Resolve();
TinyMvvm has its own implementation of ICommand that not has any references to Xamarin.Forms so you can use it in a library without reference Xamarin.Forms.
public ICommand WithParameter
{
get
{
return new TinyCommand(async() =>
{
//Do stuff
});
}
}