1
votes

I'm attempting to use the Xamarin.Forms MasterDetail page to implement a Hamburger menu navigation. The issue I'm having is that, depending on how I change the detail page, either the hamburger menu disappears but Back functionality works, or the hamburger stays but we lost the ability to navigate through the detail pages (the hardware/on screen back button returns the user to the device's home screen).

The issue is easy to replicate using the most current XF (2.3.4.247); create a new Cross Platform App (Xamarin) in Visual Studio. Ensure all Nuget packages are up to date. Then to the Shared Project, add a MasterDetail page called MyMasterPage.

By default in MyMasterDetailPage.xaml.cs in the ListView_ItemSelected there's a line Detail = new NavigationPage(page) which preserves the hamburger menu, but effectively doesn't navigate between detail pages. Pressing back on Android closed the app.

If you change the line to Detail.Navigation.PushAsync(page, true) the back button works and you can navigate through all the previously opened sub items, but the hamburger icon is replace with another back button (in addition to the one the device normally shows).

How can I get the hamburger menu to stay so the user can access it on all pages, while still allowing the user to go back to previous Detail pages?

1

1 Answers

1
votes

You need to follow this example. https://developer.xamarin.com/samples/xamarin-forms/Navigation/MasterDetailPage

On my App.xaml.cs I have it redirecting to the Menu page.

MainPage = new MainMenu();

Next I created the MainMenu view which is a MasterDetailPage

<MasterDetailPage.Master>

    <ContentPage 
            Icon="hamburger_menu.png" 
            Title="MyTitle"
            BackgroundColor="#29632A"
            >

        <!--Menu Title background color--> 

         <!--Slide out Menu--> 
        <StackLayout VerticalOptions="FillAndExpand" >

            <!--Menu Header Layout-->

            <Label 
                Text="MyTitle" 
                TextColor="White" 
                FontSize="22" 
                VerticalOptions="Center" 
                HorizontalOptions="Center" 
                Margin="0, -10, 0, 5" />

            <ListView 
                    x:Name="MenuListView"
                    ItemsSource="{Binding MainMenuItems}"
                    ItemSelected="MainMenuItem_Selected"
                    VerticalOptions="FillAndExpand" 
                    SeparatorVisibility="None" 
                    BackgroundColor="#f5f5f5">
                 <!--Menu background color--> 
                <ListView.ItemTemplate>
                    <DataTemplate>
                        <ViewCell>
                            <ViewCell.View>
                                <StackLayout Orientation="Horizontal" Padding="10,0,0,0">
                                     <!--Menu layout-->

                                    <Label Text="{Binding Title}" FontSize="18" VerticalTextAlignment="Center"/>

                                </StackLayout>
                            </ViewCell.View>
                        </ViewCell>
                    </DataTemplate>
                </ListView.ItemTemplate>
            </ListView>
        </StackLayout>

    </ContentPage>
</MasterDetailPage.Master>

The MainMenu.xaml.cs

    public partial class MainMenu : MasterDetailPage
{
    public List<MainMenuItem> MainMenuItems { get; set; }

    public MainMenu ()
    {
        BindingContext = this;

        // Build the Menu
        MainMenuItems = new List<MainMenuItem>()
        {
            new MainMenuItem() { Title = "Menu1", Icon = "menu1.png", IconSize = 18, TargetType = typeof(Menu1) },
            new MainMenuItem() { Title = "Menu2", Icon = "menu2.png", IconSize = 18, TargetType = typeof(Menu2) }
        };

        // Set the default page, this is the "home" page.
        ChangeDetail(new Menu1());
        InitializeComponent ();

    }

    // When a MenuItem is selected.
    public void MainMenuItem_Selected(object sender, SelectedItemChangedEventArgs e)
    {
        var item = e.SelectedItem as MainMenuItem;
        if (item != null)
        {
            if (item.Title.Equals("Menu1"))
            {
                ChangeDetail(new Menu1());
            }
            else if (item.Title.Equals("Menu2"))
            {
                ChangeDetail(new Menu2());
            }

            MenuListView.SelectedItem = null;
            IsPresented = false;
        }
    }

    public void ChangeDetail(Page page)
    {
        var navigationPage = Detail as NavigationPage;
        if (navigationPage != null)
        {
            navigationPage.PushAsync(page);
            return;
        }
        Detail = new NavigationPage(page) { BarBackgroundColor = Color.FromHex("#FF0000"), BarTextColor = Color.White };
    }
}