Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Change page after login in Xamarin Forms

I have xamarin form application that has login page. When user login successfully, the application navigate to MainPageMenu which is a master detail page. I have the same problem. This is my code in app.cs:

public App ()
{
    InitializeComponent();
    if (ApplicationSettings.NotLogin()) // Method to check if use if logged in or not
       MainPage = new LoginPage();            
    else            
       MainPage = new NavigationPage(new MainPageMenus());
}

In login Page, I write this code:

//Some code for login .....

MasterDetailPage fpm = new MasterDetailPage
{
      Master = new MainPageMenus(),
      Detail = new NavigationPage(new MainPage())
};
Application.Current.MainPage = fpm;

The application navigate to fpm page correctly, but the problem is that when I press menu icon, I get the detail page not the master page.

This problem is similar to one described in this post. And the code above is the selected as the answer to the question. But code doesn't work for me. In stack Overflow, there is a similar question and the answer was to use this:

Application.Current.MainPage = new NavigationPage(new MainPageMenus());

But in this case the menu icon is hidden.

Here is the Xml of MainPageMenus:

<?xml version="1.0" encoding="utf-8" ?>
<MasterDetailPage xmlns="http://xamarin.com/schemas/2014/forms"             
                  xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"             
                  x:Class="XProject.Menus.MainPageMenus"                                    
                  xmlns:local="clr-namespace:XProject"
                  Title="E-Clinic"
                  >
    <MasterDetailPage.Master>
        <ContentPage Title="Menu">
            <StackLayout Orientation="Vertical">
                <Button Clicked="GoToApplicationSettingsPage" Text="Application Settings"></Button>
                <Button Clicked="GoToHxSettingsPage" Text="Medical History Settings"></Button>
                <Button Clicked="GoToVisitsSettingsPage"  Text="Visits Settings"></Button>
                <Button Clicked="GoToCustomFieldsPage" Text="Custom Fields"></Button>
                <Button Clicked="GoToAddCustomFieldsPage" Text="Add Custom Fields"></Button>
                <Button Clicked="GoToAddCommonInfoPage" Text="Common Info"></Button>
                <Button Clicked="GoToAddStatisticsPage" Text="Statistics"></Button>
                <Button Clicked="GoToBackupPage" Text="Create Backup"></Button>
                <Button Clicked="GoToRestoreBackupPage" Text="Restore Backup"></Button>
            </StackLayout>
        </ContentPage>
    </MasterDetailPage.Master>

    <MasterDetailPage.Detail>
        <local:MainPage></local:MainPage>
    </MasterDetailPage.Detail>
</MasterDetailPage>
like image 939
Ahmed Shamel Avatar asked Feb 20 '18 18:02

Ahmed Shamel


2 Answers

This:

Application.Current.MainPage = new NavigationPage(new MainPageMenus());

is definitely wrong. Here you are assigning a NavigationPage with a MasterDetailPage as a root page. This is not gonna work, because only the detail page of the MasterDetailPage can be a navigation page. The Master Page should not be affected by the navigation.

What you should actually do is having the DETAIL PAGE of your MasterDetailPage a NavigationPage with child Pages (ContentPages).

This code is actually looking well, but the only problem is: You are setting "MainPageMenus" (which is in fact your MasterDetailPage) as the master page of ANOTHER MasterDetailPage.

//Some code for login .....

MasterDetailPage fpm = new MasterDetailPage
{
      Master = new MainPageMenus(),
      Detail = new NavigationPage(new MainPage())
};
Application.Current.MainPage = fpm;

What you should do is: Create a ContentPage that is the same as MainPageMenus and lets name it as MainPageMenusAsContentPage. The Xaml of MainPageMenusAsContentPage is:

<?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="XProject.Menus.MainPageMenusAsContentPage"
             Title="Menu"
             >
    <ContentPage.Content>
        <StackLayout Orientation="Vertical">
            <Button Clicked="GoToApplicationSettingsPage" Text="Application Settings"></Button>
            <Button Clicked="GoToHxSettingsPage" Text="Medical History Settings"></Button>
            <Button Clicked="GoToVisitsSettingsPage"  Text="Visits Settings"></Button>
            <Button Clicked="GoToCustomFieldsPage" Text="Custom Fields"></Button>
            <Button Clicked="GoToAddCustomFieldsPage" Text="Add Custom Fields"></Button>
            <Button Clicked="GoToAddCommonInfoPage" Text="Common Info"></Button>
            <Button Clicked="GoToAddStatisticsPage" Text="Statistics"></Button>
            <Button Clicked="GoToBackupPage" Text="Create Backup"></Button>
            <Button Clicked="GoToRestoreBackupPage" Text="Restore Backup"></Button>
        </StackLayout>
    </ContentPage.Content>
</ContentPage>

Then use this code:

var masterDetailPage = new MasterDetailPage()
{
    Master =new MainPageMenusAsContentPage(), 
    Detail = new NavigationPage(new MainPage())
};

Application.Current.MainPage = masterDetailPage;

EDIT: For navigation:

either masterDetailPage.Detail.PushAsync(new CoolPage()); or masterDetailPage.Detail = new NavigationPage(new CoolPage());

They behave different, the first pushes a page to the stack, the second replaces the current detail page

like image 78
Csharpest Avatar answered Nov 08 '22 21:11

Csharpest


For the reference, from the official documentation:

A MasterDetailPage is designed to be a root page, and using it as a child page in other page types could result in unexpected and inconsistent behavior. In addition, it's recommended that the master page of a MasterDetailPage should always be a ContentPage instance, and that the detail page should only be populated with TabbedPage, NavigationPage, and ContentPage instances. This will help to ensure a consistent user experience across all platforms.

Commonly, mobile applications communicate with APIs using an authentication token which may expire or get rejected any moment. Which means that you also have to be prepared for user re-authentication any moment. In this case, your MainPage can be freely a MasterDetailPage and a login page could come as a modal page on a top of it when it or any other page when it is required.

like image 3
EvZ Avatar answered Nov 08 '22 19:11

EvZ