In this post, we will look at using Xamarin Forms in a more reactive manner, which will give more control over validation and synchronous UI updates, with potential to easily add custom animations.
The primary components for a Xamarin Forms mobile app are view models, presenters, services, repositories, business layers, DTOs etc. All interaction with a mobile app can be thought of as a series of asynchronous events handled by the view model. All interactions with the underlying layer, i.e services, notifications, data layers, picking a photo, communicating over the network, are all a series of asynchronous events. All of these events collectively update the UI in a meaningful way for the user.
Traditional properties in MVVM pattern are all defined as public properties in view models. Changes in the values trigger changes in the UI (such as text, enabled state etc.). All of this usually happens using reflection, matching string based bindings to the actual property names. This, though easy to implement, slows down the UI updates, and also the developer loses control over how the state change happens. To handle this we will use reactive observable properties instead of data properties.
Here is how we define an IObservableObject, which we use to subscribe to the properties:
Here is a simple implementation of the above contract:
In the above implementation, subscribers are simply saved in a list. Any change in value triggers a call to all subscribers. Value is also published when the subscriber is added. Care should be taken to appropriately unsubscribe from the property to prevent any memory leaks.
Let us see an example of how to use the above property.
Consider the following notification service contract, and a view model that uses the contract.
In above case, the view model listens to property changes by passing an action to be called whenever the data changes. In our implementation, this action will be called very first time as well, if data is already available. This also prevents us from calling service methods multiple times. For example, consider an enterprise application that shows list of driver deliveries on the first page, and shows the list of items in the next. Since the source of the data is always same, both view models (for list, and count) can just observe the same data source for changes, and the LoadNotifications can be called from a dedicated central place.
The above view model uses a presenter as well. This presenter is the contract between the view model and the actual user interface. Whenever the data changes, the action will be called and then UI can update the data in a meaningful way to the user, such as with animations or transitions.
We also improve the reusability of UI by using the above properties. Since XAML contains view model bindings, sharing child views across different screens is error prone, tedious and requires a lot of redundant code. By adding a presenter contract between the UI and the view model we get the control of updating UI in the required manner.
Thus, by using the above reactive properties, we get control over UI transitions, XAML re-use, and also preventing expensive data and network calls to load data properties.