Use MasterDetail page (Menu) and Navigation page in a project

ArefinArefin USMember, University ✭✭

Hello All,

I am developing XF app for iOS and Andorid. I need to use Menu in my project. I followed this article to use MasterDetail navigation page - https://www.syntaxismyui.com/xamarin-forms-masterdetail-page-navigation-recipe/. And it is working fine.

But now I need to use navigation page before using MasterDetails page. Let me explain with an example -

*** LoginPage.cs is a simple content page that will be shown when app starts. After successful login app will show Menu (using MasterDetail navigation page).

  1. In my App.cs file I have used
    MainPage = new LoginPage ();

  2. In LoginPage after successfully login, I am using the code to load Menu (MasterDetails page)
    Application.Current.MainPage = new RootPage () // RootPage is a subclass of MasterDetail page

But problem is - after showing Menu, app is crashing without not showing any message in application log. I investigated and debug and found that app is crashing due to "Application.Current.MainPage = new RootPage ()". Though this code should be work.

So, my question is what is the best practice to use MasterDetail page after using normal navigation page ( MainPage = new LoginPage (); ).

Any suggestion will be highly appreciable!

Thank you,
Arefin

Best Answer

Answers

  • AndreasBrostenAndreasBrosten USMember ✭✭

    Why not let your MD-page be the root page from start and push your login-page on top of it? After successful login, you just pop the login-page and lands on the MD-page.

  • AlessandroCaliaroAlessandroCaliaro ITMember ✭✭✭✭✭

    @Arefin

    This is how I work

    in "App" I create
    public static MasterDetail MD {get;set;}

    then
    MD = new MasterDetail();
    MD.Master = new PageMaster();
    MD.Detail = new PageDetail();

    Application.Current.MainPage = MD;

    If you want "Detail" as a NavigationPage, in App

    public static NavigationPage Detail {get;set;}

    and

    MD = new MasterDetail();
    MD.Master = new PageMaster();
    Detail = new NavigationPage(new PageDetail());
    MD.Detail = Detail;

    I've not compiled... but it should works.
    Let me know

  • ArefinArefin USMember, University ✭✭

    @AndreasBrosten , Thanks for your suggestion.
    But I don't want to show Menu before login. So, can't I use MasterDetails page (Menu) after using navigation page?

  • ArefinArefin USMember, University ✭✭

    @AlessandroCaliaro: Thanks! But I want to show/set MasterDetails page after successful login and the LoginPage.cs is very simple content page where user will just put username and password.

    So, what do you think for this situation?

    Thanks,
    Arefin

  • AlessandroCaliaroAlessandroCaliaro ITMember ✭✭✭✭✭

    yes @Arefin, you can paste the code I've written inside (for example) the clicked button event of your Login Page

    Button.Clicked +=..... the code I've written.

  • ylemsoulylemsoul RUMember ✭✭✭

    MainPage = new NavigationPage(new LoginPage());

    In LoginPage you can disable navigation bar if you wish

  • ArefinArefin USMember, University ✭✭
    edited June 2015

    @Alessandro Caliaro: Thanks! But I am not sure how your code will work in my code. Better let me share my MasterDetailsPage code, you will get a clear idea. Please check the attached file.

    And I need to use this page in my button clicked - like "Application.Current.MainPage = new RootPage ();" And this code should work but not working. Here is the code:

    public class RootPage : MasterDetailPage
        {
            MenuPage menuPage;
    
            public RootPage ()
            {
                menuPage = new MenuPage ();
    
                menuPage.Menu.ItemSelected += (sender, e) => NavigateTo (e.SelectedItem as MenuItem);
    
                Master = menuPage;
                Detail = new NavigationPage (new HomePage ());
    
    
            }
    
            public RootPage (ContentPage contentPage)
            {
                menuPage = new MenuPage ();
    
                menuPage.Menu.ItemSelected += (sender, e) => NavigateTo (e.SelectedItem as MenuItem);
    
                Master = menuPage;
                Detail = new NavigationPage (contentPage);
    
            }
    
            void NavigateTo (MenuItem menu)
            {
                if (menu == null)
                    return;
                if (menu.Title == "Home") {
                    Detail = new NavigationPage (new HomePage ());
                } else if (menu.Title == "Leads") {
                    Detail = new NavigationPage (new LeadsPage ());
                } else if (menu.Title == "Signin") {
                    Detail = new NavigationPage (new LoginPage ());
                } else if (menu.Title == "Signup") {
                    Detail = new NavigationPage (new SignUpPage ());
                } else if (menu.Title == "Logout") {
                    doLogOut ();
                } else if (menu.Title == "Profile") {
                    if (Application.Current.Properties.ContainsKey (Constants.USER_EMAIL)) {
                        if (!string.IsNullOrEmpty ((string)Application.Current.Properties [Constants.USER_EMAIL])) {
                            Detail = new NavigationPage (new ProfilePage ());
                        }
                    } else {
                        Detail = new NavigationPage (new EditRegisterPage ());  
                    }
    
                } else if (menu.Title == "News") {
                    Detail = new NavigationPage (new NewsPage ());
                } else if (menu.Title == "Change password") {
                    Detail = new NavigationPage (new ChangePasswordPage());
                }else if (menu.Title == "Change location") {
                    Detail = new NavigationPage (new ChangeLocation());
                }
    
                menuPage.Menu.SelectedItem = null;
                IsPresented = false;
    
                Insights.Identify(Insights.Traits.GuestIdentifier, null);
                Insights.Track (Constants.FinishRegisterPage, new Dictionary<string,string> {
                    {"Device ID",Constants.GetDeviceUDID()},
                    {"Source file","RootPage.cs"},
                    {"Menu item", menu.Title},
                    {"Event","Tap"}
                });
            }
    
    
        }
    
  • AlessandroCaliaroAlessandroCaliaro ITMember ✭✭✭✭✭

    @Arefin , understand now but this is not the way I use master detail, sorry.
    If you put the "Application.Current.MainPage = new RootPage ()" in a try catch which exception do you have?

  • JoeMankeJoeManke USMember ✭✭✭✭✭

    I'm going to guess the exception is something to do with changing the main page from the current main page. I have the same navigation structure in one of my apps (login page -> MasterDetail with detail being a NavigationPage). We accomplished it by changing the main page from the App class in a PropertyChanged handler, listening to the SignInViewModel.

  • ArefinArefin USMember, University ✭✭

    @Joe Manke: Can you please elaborate your approach? It will be really great for me as I am stuck on this.

  • ArefinArefin USMember, University ✭✭

    @Alessandro Caliaro: Thanks! Can you please share any technique to solve my issue? I am also searching to find any solution.

  • MaxMengMaxMeng NZMember ✭✭✭
    edited June 2015

    If I remember, you cannot change MainPage after Form.Init() called.

    What I did was let NavigationPage to be the MainPage, and
    if User is signed in, then PushAsync(new HomePage);
    else then PushAsync(new LoginPage);
    And in LoginPage, after user logged in; in the LoginPage, call Navigation.InsertPageBefore(new HomePage, this(which is LoginPage)) and then call PopAsync.

    I prefer to use NavigationPage as MainPage instead of using MasterDetailPage.

  • ArefinArefin USMember, University ✭✭

    @Max Meng: Thanks! Did you get my requirement? I have to use MasterDetail page (Menu) after using Navigation page.

  • AlessandroCaliaroAlessandroCaliaro ITMember ✭✭✭✭✭

    @arefin take a look at the attach project

  • ArefinArefin USMember, University ✭✭

    @Joe Manke, and @ Alessandro Caliaro Thanks, let me check tomorrow and revert you.

    BTW, I fixed the issue with my own way and it is working! I will share details tomorrow.

  • ArefinArefin USMember, University ✭✭
    edited June 2015

    @Joe Manke, I like your approach. Thank you!

    @Alessandro Caliaro, Thanks. Basically your code will not work always if there are some pages in Navigation stack and change the current manin page with MasterDetails.

    So, what I did to fix the issue. Here is the code.

        if (Device.OS == TargetPlatform.iOS) {
                Navigation.PopToRootAsync();
                Application.Current.MainPage = new RootPage();
        }else{
                Application.Current.MainPage = new RootPage();
        }
    

    As I am using Xamarin.Forms (pcl) so, I wrote the code in pcl project. But I found for Android, if I use Navigation.PopToRootAsync(), the app is not working. So, for Android, we need to use only Application.Current.MainPage = new RootPage();

    Thanks a lot for your help!

  • batmacibatmaci DEMember ✭✭✭✭✭

    @Arefin said:
    @Joe Manke, I like your approach. Thank you!

    @Alessandro Caliaro, Thanks. Basically your code will not work always if there are some pages in Navigation stack and change the current manin page with MasterDetails.

    So, what I did to fix the issue. Here is the code.

        if (Device.OS == TargetPlatform.iOS) {
              Navigation.PopToRootAsync();
              Application.Current.MainPage = new RootPage();
        }else{
              Application.Current.MainPage = new RootPage();
        }
    

    As I am using Xamarin.Forms (pcl) so, I wrote the code in pcl project. But I found for Android, if I use Navigation.PopToRootAsync(), the app is not working. So, for Android, we need to use only Application.Current.MainPage = new RootPage();

    Thanks a lot for your help!

    where is the sample from JoeMonke? I cant see it. I have similar requirement. can you please enlighten the solution? thanks

  • JoeMankeJoeManke USMember ✭✭✭✭✭

    @batmaci I guess the attachment was removed at some point, probably to save server space. I found it on my end, so I've re-uploaded it attached to this comment.

  • Vikram_BVikram_B USMember ✭✭

    I have the same issue with the MasterDeatil page when successfully login it has to show the master detail page.but it is not working......

  • ASHISHKUMAR.2836ASHISHKUMAR.2836 USMember

    The sample works fine but I am not able to handle the menu item click ,can somebody help ?

  • AsfendYarAsfendYar USMember ✭✭

    I'm also confuse with the Master Detail Page in Xamarin Forms.Anyone please help me

  • AlessandroCaliaroAlessandroCaliaro ITMember ✭✭✭✭✭

    @AsfendYar why are you confused?

  • AsfendYarAsfendYar USMember ✭✭

    @AlessandroCaliaro Because I have tried the button code in MasterDetail Page what if I want the ListView in MasterDetailPage ?

  • AlessandroCaliaroAlessandroCaliaro ITMember ✭✭✭✭✭

    Sorry, I have non understand

  • Raj22Raj22 USMember ✭✭
    edited July 2016

    Thank you for the example. How do I control Open and closing of the Drawer in your example? I have 3 buttons in Listview:the moment I click one button Drawer should close. Ispresented is the only way? Thanks!

  • when i navigate between detail page and menu page it shows specified cast not valid.
    could anyone be able to help me on this issue please...

  • RishitoshGourRishitoshGour USMember ✭✭

    After successful logged In, I put the master detail page to load the menu items. But when i clicked on menu item to go on some detail page, I don't want to see the hamburger icon and menu items list in detail pages. I just want a Back arrow (Like Navigation Page) icon in detail page. What should i do? Please help.

    Thanks !

  • voidstreamvoidstream FRMember ✭✭✭
    edited November 2016

    @RishitoshGour said:
    After successful logged In, I put the master detail page to load the menu items. But when i clicked on menu item to go on some detail page, I don't want to see the hamburger icon and menu items list in detail pages. I just want a Back arrow (Like Navigation Page) icon in detail page. What should i do? Please help.

    Thanks !

    In App.cs:
    MainPage = new Connection();

    If connection is okay i do this:
    App.Current.MainPage = new MasterDetailPage { Master = new Menu(), Detail = new NavigationPage(new Home()) };

    For switch page:
    NavigationPage NP = ((NavigationPage)((MasterDetailPage)App.Current.MainPage).Detail);
    NP.PushAsync(new Home());
    NP.PushAsync(new Contact());
    etc...

    Works fine for me!

  • RishitoshGourRishitoshGour USMember ✭✭

    Thanks TonyPinot.. works fine!

  • awaisshabirawaisshabir USMember ✭✭

    public partial class App : Application
    {
    public static bool userIsLogin { get; set; }
    public App()
    {
    InitializeComponent();
    if (!userIsLogin)
    MainPage = new NavigationPage(new App3.Views.LoginPage()) {BarBackgroundColor=Color.Black };
    else
    MainPage = new Dashboard();// dashboard page is my master Detail page
    }
    }
    // login page
    public partial class LoginPage : ContentPage
    {
    public LoginPage()
    {
    Title = "Wellcome to login page";

        var button = new Button() { Text = "Login" };
    
        var entry = new StackLayout { Padding = 20, Spacing = 20, Children = { button } };
        Content = entry;
    
        button.Clicked += (sender, arg) => {
    
            App.userIsLogin = true;
            App.Current.MainPage = new Dashboard();
        };
    }
    

    }

  • AMORFAIROUZAMORFAIROUZ USMember ✭✭

    After successful logged In, I put the master detail page to load the menu items. But when i clicked on menu item to go on some detail pagei can't see the icon of the hamburger menu
    i'm working with PCL and i test on UWP (universal app)
    Please help.
    Thanks !

  • meljohnmeljohn USMember

    public class MenuItem
    {
    public string Title { get; set; }
    public Type TargetType { get; set; }

    }
    

    how to add logout here?

  • MuhammadUsman.2067MuhammadUsman.2067 USMember ✭✭

    Hi Everyone,
    i have a problem please help me.
    when i use icon to display masterdetailpage.Master then a white space shows on detail page. Here is screen shot of this please guide me how to get rid of it.

  • AntonioSaucedaAntonioSauceda USMember
    edited April 2017

    In IOS 10.3 with Iphone 7 Emulator show this message **"MasterDetailPage navigation needs to be updated this app will not work with future versions of ios." ** Master Detail will be deprecated!???

  • AicBodAicBod USMember ✭✭

    @voidstream it worked for me :smile:

  • voidstreamvoidstream FRMember ✭✭✭
    edited June 2017

    @AicBod said:
    @voidstream it worked for me :smile:

    No problem :)

    If you start Xamarin, i invit you to try PRISM ! It's really cool for navigation / mvvm design pattern :smile:

    Really thanks to @BrianLagunas !

  • Matt_PerleyMatt_Perley CAMember ✭✭

    @meljohn

    just posting incase someone else was wondering. ive done it this way.

    example model:
    public class MenuItem
    {
    public string Title { get; set; }
    public Type TargetType = null;
    }

    title = "Logout"

    in ListView_ItemSelected() -->
    if(ListView_ItemSelected.title == "LogOut") {
    LogOut();
    }

  • @voidstream

    As you said, Navigation is works fine for me. But i don't want to see the toolbar items list in the Detail page. It will show only Back arrow like Navigation page. Please suggest me how to do this one.

    Thanks!

Sign In or Register to comment.