Daniel Hindrikes
Developer and architect with focus on mobile- and cloud solutions!
Developer and architect with focus on mobile- and cloud solutions!
In this post, I will describe how I have created base classes for my views and ViewModels in my latest projects. It will probably break some of the MVVM rules, but I think this is a productive way to work. Please leave a comment about your thoughts about in a comment below.
First of all, I'm creating the base ViewModel. I'm adding three virtual methods, Init, OnAppearing and OnDisappering. I'm making the methods virtual so I can override them in the view models if I want.
My idea is that Init() will run after the ViewModel has been created. OnAppearing when a view appearing on the screen and disappearing when the view is disappearing. To place them in the base class for the view models makes it possible to call them from a base class for my views so I don't have to write code for calling them in every view I'm creating.
If I using an MVVM framework (I'm used to using MvvmLight) my base ViewModel will inherit the base ViewModel from the framework I'm using. But this example will show how it will be without any framework.
public abstract class BaseViewModel : INotifyPropertyChanged
{
public event PropertyChangedEventArgs PropertyChanged;
public async virtual Task Init()
{
}
public async virtual Task OnAppearing()
{
}
public async virtual Task OnDisappearing()
{
}
}
My base view will be generic to define what ViewModel I will use for the current view. I will also say the generic type has to inherit from BaseViewModel so it not can be used with other types of object. This also makes it possible for me to call the methods I created in the BaseViewModel. In the constructor, I will use my IoC to create an instance of the ViewModel.
public abstract class BaseView : ContentPage where T : BaseViewModel
{
private BaseViewModel _viewModel;
public BaseView()
{
//IoCHelper is an own defined class for resolving types that are defined in an IoC container
_viewModel = IoCHelper.Resolve();
BindingContext = _viewModel;
viewModel.Init();
}
public async override void OnAppearing()
{
base.OnAppearing();
await _viewModel.OnAppearing();
}
public async override void OnDisappearing()
{
base.OnDisappering();
await _viewModel.OnDisappering();
}
}
To define what ViewModel that should be used for the view in XAML you can do that by using x:TypeArguments like in the example below. This means that you don't have to write any code in the code-behind. Don't forget to remove that the view inherits from ContentPage in the code-behind of the view.