0

I have a login/register page, and I want to be able to navigate between them routing navigation (//LoginPage) like in a web app. I cant really make it work. I have built a AppShell.xaml page and i have registered my LoginPage and RegisterPage in App.xaml.cs (I have tried registering them in AppShell.xaml.cs too) and I have a viewmodel that has 2 functions for navigating between login and register pages but when I click on the button to navigate I get this

System.NullReferenceException: 'Object reference not set to an instance of an object.'

Here is my view-model

namespace Appointments.ViewModels
{
    public class RegLogViewModel : BaseViewModel
    {
        public AsyncCommand GoToRegisterCommand { get; }
        public AsyncCommand GoToLoginCommand { get; }
        public RegLogViewModel()
        {
            GoToLoginCommand = new AsyncCommand(GoToLogin);
            GoToRegisterCommand = new AsyncCommand(GoToRegister);
        }
async Task GoToRegister()
        {
            await Shell.Current.GoToAsync($"//{ nameof(RegisterPage)}");
        }

        async Task GoToLogin()
        {
            await Shell.Current.GoToAsync($"//{ nameof(LoginPage)}");
        }   
}

My AppShell.xaml

<Shell xmlns="http://xamarin.com/schemas/2014/forms"
             xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
             x:Class="Appointments.AppShell"
             xmlns:views="clr-namespace:Appointments.Views">

     //// I HAVE TRIED WITH AND WITHOUT THIS  SHELLCONTENT\\\\\

    <ShellContent Route="LoginPage" ContentTemplate="{DataTemplate views:LoginPage}"/>
    <ShellContent Route="RegisterPage" ContentTemplate="{DataTemplate views:RegisterPage}"/>
</Shell>

My AppShell.xaml.cs

namespace Appointments
{

    public partial class AppShell : Shell
    {
        public AppShell()
        {
            InitializeComponent();
        }
    }
}

My App.xaml.cs

namespace Appointments
{
    public partial class App : Application
    {
        public App()
        {
            InitializeComponent();
 
            MainPage = new LoginPage();
        }
    }
}

And Login.xaml

<ContentPage xmlns="http://xamarin.com/schemas/2014/forms"
             xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml" 
             xmlns:viewmodels="clr-namespace:Appointments.ViewModels"
             x:DataType="viewmodels:RegLogViewModel"
             x:Class="Appointments.Views.LoginPage">

    <ContentPage.Content>
        <StackLayout>
            <Label 
                Text="Login Page!"
                FontSize="Title"
                VerticalOptions="CenterAndExpand" 
                HorizontalOptions="CenterAndExpand" />
            
            <Label
                Text="{Binding Name}"/>

            <Entry
                Text="{Binding Name}"/>

            <Button
                Text="Go To Registration"
                Command="{Binding GoToRegisterCommand}"/>
            
            <ActivityIndicator IsRunning="{Binding IsBusy, Mode=OneWay}"/>
        </StackLayout>

    </ContentPage.Content>
</ContentPage>
Nicoara
  • 318
  • 2
  • 15
  • I am confused from one side your `App.MainPage` is `LoginPage` and from the other side you are defining but not using AppShell. – Cfun Jun 12 '21 at 15:06
  • I was not aware that I had to initialize my App.MainPage with AppShell. I thought that App.MainPage sets my starting page but clearly I was wrong – Nicoara Jun 12 '21 at 15:10
  • What actually sets the starting page? – Nicoara Jun 12 '21 at 15:10
  • Yes it does set your main page but if you set it to LoginPage then you will have to later reset it somehow to AppShell otherwise the Shell won't be used. I prefer the design where to start and stay in AppShell while handling my login/register stuff: [How can you restrict/control the navigation routes the user can visit based on login status/role?](https://stackoverflow.com/q/65186262/5228202) (could be a duplicate to this). – Cfun Jun 12 '21 at 15:19

1 Answers1

0

The problem was that in App.xaml.cs I have

MainPage = new LoginPage();

but I had to use

MainPage = new AppShell();

it will work but now I don't understand how the app knows to open my LoginPage first and not RegisterPage or any other page

Nicoara
  • 318
  • 2
  • 15