BindableModel

RedCorners.Forms.BindableModel is an ideal type to be used as a view model in Xamarin.Forms. Implementing INotifyPropertyChanged, it offers a number of handy tools for updating bindable properties.

SetProperty(...)

To define a simple property and notify property change on it, the following pattern is used:

public class CounterViewModel : BindableModel
{
    int _counter = 0;
    public int Counter
    {
        get => _counter;
        set => SetProperty(ref _counter, value);
    }

    public void Count()
    {
        Counter++;
    }
}

RaisePropertyChanged(...)

To signal property change on a different property, you can use RaisePropertyChanged(...):

public class CounterViewModel : BindableModel
{
    int _counter = 0;
    public int DoubleCounter => Counter * 2;
    public int Counter
    {
        get => _counter;
        set 
        {
            SetProperty(ref _counter, value);
            RaisePropertyChanged(nameof(DoubleCounter));
        }
    }

    public void Count()
    {
        Counter++;
    }
}

UpdateProperties()

The UpdateProperties() method automatically signals the property change for all of the public methods of the view model. While it has a huge performance impact, it’s the easiest way to update the UI with the least amount of code. Use it when you want to keep your code clean and the performance impact is not important.

public class CounterViewModel : BindableModel
{
    public string Title { get; set; } = "Hello, BindableModel!";
    public int Counter { get; set; } = 0;
    public int DoubleCounter => Counter * 2;

    public void Count()
    {
        Counter++;
        UpdateProperties();
    }
}

In the example above, when UpdateProperties() is called, RaisePropertyChanged is called for both Counter and Title.

Certain properties, like Title, are less likely to change. They can be excluded from UpdateProperties() by adding a [ManualUpdate] attribute behind them. Properties marked with [ManualUpdate] are not updated by UpdateProperties(), and require manual calls to RaisePropertyChanged():

public class CounterViewModel : BindableModel
{
    [ManualUpdate] public string Title { get; set; } = "Hello, BindableModel!";
    public int Counter { get; set; } = 0;
    public int DoubleCounter => Counter * 2;

    public void Count()
    {
        Counter++;
        UpdateProperties();
    }
}

In case you definitely want to update all properties, including the ones marked with [ManualUpdate], you can call:

UpdateProperties(forceAll: true);

UpdateProperties always runs on the main thread, even when used from within an asynchronous method. This is the thread obtained by calling Xamarin.Forms.Device.BeginInvokeOnMainThread.