Xamarin MVVM Data-Binding and Command Example using Code-based views

A brief and quick example using a ‘login’ form to get you started:

  • View
public Entry usernameField;
public LoginViewModel viewModel = new LoginViewModel();
BindingContext = viewModel;

nameField = new Entry()
{
Placeholder = "Username",
};
nameField.SetBinding(Entry.TextProperty, new Binding("User", BindingMode.TwoWay));
passField = new Entry()
{
Placeholder = "Password",
};
passField.SetBinding(Entry.TextProperty, new Binding("Pass", BindingMode.TwoWay));
Button loginButton = new Button
{
Text = "LOGIN",
};
loginButton.SetBinding(Button.CommandParameterProperty, new Binding("."));
loginButton.SetBinding(Button.CommandProperty, new Binding("LoginFormCommand"));

In the view above we create two entry fields and a button. After each object is instantiated, we use the SetBinding method to create a new lifeline between this UI object and a variable on the back-end. The program knows how to find the variable in question, denoted within quotations in the setBinding property, because we initially give it the conext at the top of the view BindingContext = viewModel;

The button is treated similarly but we notice that it uses a Command property to set the binding. The key here is creating the setBinding property with the name of the command in your viewmodel, which in my case is the LoginFormCommand.

This Command feature allows us to call a function directly in the ViewModel without using the OnClicked event handling syntax in the view. The point is to remove more of the dynamic logic from the view and insert it directly into the viewmodel.

ViewModel:

There is a bit of overhead to enable data-binding in the viewModel. Keep in mind some of this can be set in a base viewModel and inherited from to keep the business logic cleaner such as the first excerpt below.

public class LoginFormViewModel 
{
public ICommand LoginFormCommand { get; private set; }
private string _user;
private string _pass;
public LoginViewModel()
{
LoginFormCommand = new Command(LogUserIn());
}
public string User {
get => _user;
set
{
if (_userName != value){ _userName = value;}
OnPropertyChanged();
}
}
public string Pass {
get => _pass;
set
{
if (_userName != value){ _userName = value;}
OnPropertyChanged();
}
}
public LogUserIn()
{
bool IamLoggedIn = AFunctionThatCallsAWebService(User, Pass);
}
//--------------Below this line is setup-------------//
/// <summary>
/// used to instill two-way data binding between a viewmodel's properties and a given view object.
/// </summary>
public event PropertyChangedEventHandler PropertyChanged;
public void OnPropertyChanged([CallerMemberName] string propertyName = null)
{
var handler = PropertyChanged;
handler?.Invoke(this, new PropertyChangedEventArgs(propertyName));
}

Each private property has a public setter where the OnPropertyChanged() function is called. Using an attribute [CallerMemberName] shown at the bottom of the viewmodel, we can automate the process of passing in the calling object name.

When the Button is clicked, it calls the ICommand.Execute method of the object bound to its Command property which we see in the constructor. Therefore, the LogUserIn method is called. We can pass in the User and Pass public properties and thanks to the data binding, these will contain whatever values were inserted into the text fields of the view.