Problems in Master Detail navigation in Xamarin Forms

Asked

Viewed 380 times

0

I’m having problems understanding how the Master Detail type navigation works in Xamarin Forms, let’s go to my code as it is now:

1- I created a interface for navigation:

using System.Threading.Tasks;

namespace MobileApp.Services
{
    public interface INavigationService
    {
        Task NavigateToLogin();
        Task NavigateToRegister();
        Task NavigateToMain();
        Task NavigateToCoupons();
        Task NavigateToProfile();
    }
}

2- I created the classe that implements the interface:

using MobileApp.Views;
using System.Threading.Tasks;
using System;

namespace MobileAPP.Services
{
    public class NavigationService : INavigationService
    {
        public async Task NavigateToCoupons()
        {
            await App.Current.MainPage.Navigation.PushAsync(new CouponsView());
        }

        public async Task NavigateToLogin()
        {
            await App.Current.MainPage.Navigation.PushAsync(new LoginView());
        }

        public async Task NavigateToMain()
        {
            await App.Current.MainPage.Navigation.PushAsync(new MainView());
        }

        public async Task NavigateToRegister()
        {
            await App.Current.MainPage.Navigation.PushAsync(new RegisterView());
        }

        public async Task NavigateToProfile()
        {
            await App.Current.MainPage.Navigation.PushAsync(new ProfileView());
        }
    }
}

3- This is mine MainView who inherits from MasterDetailPage and configure the master and the detail.

using Xamarin.Forms;

namespace MobileApp.Views
{
    public partial class MainView : MasterDetailPage
    {
        public MainView()
        {
            InitializeComponent();

            this.Master = new MasterView();
            this.Detail = new NavigationPage(new DetailView());
        }
    }
}

4- My home screen is view of Login, and I only have one método where you check your credentials. Login ok, I already use the interface navigation to the MainView and works perfectly, at that point I have no problem. Follows the código:

private async void Login()
        {
            var IsAuthenticated = await _authenticate.Login(Email, Password);
            if (!string.IsNullOrEmpty(IsAuthenticated))
            {
                await this._navigationService.NavigateToMain();
            }
            else
            {
                await this._messageService.ShowAsync("Email ou senha invalidos");
            }
        }

5- The problem occurs in the MasterView, which is the side menu. I have several Button that lead to other pages, follows the código of MasterViewModel:

using MobileApp.Services;
using System.Windows.Input;
using Xamarin.Forms;
using System;

namespace MobileApp.ViewModels
{
    class MasterViewModel : ViewModelBase
    {
        private readonly IMessageService _messageService;
        private readonly INavigationService _navigationService;

        public ICommand CouponsCommand { get; set; }
        public ICommand ProfileCommand { get; set; }

        public MasterViewModel()
        {
            this.CouponsCommand = new Command(this.Coupons);
            this.ProfileCommand = new Command(this.Profile);
        }

        private async void Profile()
        {
            await this._navigationService.NavigateToProfile();
        }

        private async void Coupons()
        {
            await this._navigationService.NavigateToCoupons();
        }
    }
}

When I try to navigate the error occurs: Object reference not set to an instance of an object. by clicking on any button. But as you can see in the implementation of interface navigation I am instanciando a página, as it occurs after the Login that leads to MainView and it works fine. If I remove the código using the interface _navigationService and put the same código who is in the classe NavigationService in Profile, for example:

private async void Profile()
{
   await App.Current.MainPage.Navigation.PushAsync(new ProfileView());
}

private async void Coupons()
{
   await this._navigationService.NavigateToCoupons();
}

So navigation works, I don’t really understand what’s going wrong. An observation; I’m not using any framework for MVVM (like mvvmcross, prismmvvm, etc) because first I want to learn how it all works. Someone can explain where the error is?

  • 1

    I’m assuming that private readonly INavigationService _navigationService; is not being initialized because of this error. In my view _navigationService some value should be initialized or set in the constructor method.

  • @rubStackOverflow, that’s right! My inattention, the login screen looks like this, and that’s why it works. You can put as answer.

1 answer

1


Hello.

From what I see you’re trying to use addiction injection, right ? You remembered to register your classes/interfaces ?

If not, try to register them before using. Register in your App() class constructor using the Dependencyservice Register method.

Ex:

public App()
    {
            // The root page of your application
            DependencyService.Register<INavigationService, NavigationService >();
            InitializeComponent();


    }

Also remember to "load" your dependency before using, for example:

In the class to use navigation...

        internal readonly INavigationService _Navigation;
        _Navigation = DependencyService.Get<INavigationService>();
  • I forgot to put the App code, but what you said was already being done, the solution was just what rubStackOverflow said, and you also remembered, to load the dependency in viewmodel.

Browser other questions tagged

You are not signed in. Login or sign up in order to post.