c# – Navigation with standard MVVM Xamarin Forms

Question:

I recently started studying Xamarin Forms. I have a question that can be clarified here: how to navigate between pages using MVVM? Should navigation be on vm or view ?

Example

<?xml version="1.0" encoding="utf-8" ?>
<ContentPage xmlns="http://xamarin.com/schemas/2014/forms"
     xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
     x:Class="GeoMobile.Views.Login">
     <StackLayout>
        <Label Text="GEO Mobile" VerticalOptions="Center" HorizontalOptions="Center" />
        <Entry Text="{Binding Email}" Placeholder="Email" />
        <Entry Text="{Binding Senha}" Placeholder="Senha" />
        <Button Text="Entrar" Command="{Binding Entrar}" />
        <Button Text="Registrar" />
     </StackLayout>
</ContentPage>

Login.cs

public partial class Login : ContentPage
{
    public Login()
    {
        InitializeComponent();
        this.BindingContext = new LoginVM(Entrar);
    }

    public async void Entrar()
    {
        Navigation.InsertPageBefore(new Master__(), this);
        await Navigation.PopAsync();
    }
}

And on my vm :

public class LoginVM : ObservableBase
{
    private string _email;

    public string Email
    {
        get { return _email; }
        protected set
        {
            _email = value;
            OnPropertyChanged();
        }
    }

    private string _senha;

    public string Senha
    {
        get { return _senha; }
        set
        {
            _senha = value;
            OnPropertyChanged();
        }
    }

    public Command Entrar { get; private set; }
    private Action loginOk;

    private void login()
    {
        //checagem antes de ir para a proxima pagina
        loginOk();
    }

    public LoginVM(Action loginOk)
    {
        this.loginOk = loginOk;
        Entrar = new Command(login);
    }
}

I got the navigation passing an action in the vm constructor, but I need to implement another navigation for the register button, but for that I would have to pass another action in the constructor and I believe that this would not be a good practice.

If you put browsing on vm, the software testing process will be hampered. What is the best way around the problem?

Answer:

By definition I believe that navigation should be done in your VM, your View should only be used for layout purposes. Of course this is not a rule and if you need to use something in your View for any problem that is occurring in the VM, you won't let your app bug because of it, but by default mvvm I think the most correct would be on your vm .

Usually I create a "service" and in my base view model I use it by dependency injection. It works fine, I never had any problems.

I recommend this Video by Angelo Belchior, it illustrates well what I wrote above.

Scroll to Top