A ViewModel is the orchestrator between the View and Model. ViewModels are designed to be as simple as possible, with no business logic inside them but small logic to handle routing of messages to and from the View and other Models within the app. As mentioned in day 3 we bind the ViewModel to the View in the Page Build Service. Because the ViewModel is the focal point of where data communication and navigation events should be happening, we need to pass events that happen in other areas to the ViewModel.
Passing View Events
There is no way for the ViewModel to know what is happening with the page unless you pass it along. As you will see in the Base Folder in the GitHub project you will see that BasePage.xaml.cs passes events to BaseViewModel.cs. The point here is that the code for passing the events is in inherited BasePage, as the goal is to make sure all Views have zero code behind. Just to be clear, XAML and nothing else except the default empty code behind file.
Navigation Service OnNavigated and Parameter Passing
If you have developed Xamarin apps before you will know it can be tricky to determine when the page is loaded for the first time, compared to OnAppearing, which can occur on first load or when they come back to the page on the Navigation Stack. Also rather than having some form of StateManager in the application, you can pass parameters to each page which is normally much easier to maintain than a globally accessible state. When we build the page we send the parameter to the ViewModel’s OnNavigated method. This is just an empty virtual method in the BaseViewModel that can be overridden by ViewModels on an as needed basis.
In order to get the ViewModel to take an action, a bindable command property is normally set on the View. The ViewModel then normally relays this to the model, NavigationService or some other service.
Exposing Model Properties
The final aspect is exposing and binding the properties of the model to the view. Since the model doesn’t have a direct line to the View you have 2 options:
- Add a Model property in your ViewModel and bind to that.
- Recreate each property in the ViewModel that is in the Model.
The preferred approach is it depends. I personally tend to stick with having the Model as a property you bind to in the ViewModel. Such as (as seen in LoginViewModel.cs)
If you need to provide some more information or control to a property specifically for the View, then I would wrap around a specific property in the ViewModel and just pass it along.
There is no specific rule on what you should take here, though having the Model in the ViewModel reduces a lot code, especially for Model’s with a large amount of properties.