MAUI: Issue with displaying Flyout menu page

Sreenivasan, Sreejith 80 Reputation points
2025-10-23T14:19:50.52+00:00

My app’s home page is a FlyoutPage.

The Flyout part is my menu.

The Detail part is a DashboardTabPage, which has three child tabs.

The problem I’m facing is this:

  • When I open the menu for the first time, it works fine.
  • But after I close it, if I try to open it again while still on the Dashboard tab, it doesn’t open.
  • However, if I switch to another tab first and then try to open the menu, it opens normally.

Adding the DashboardTabPage full code below:


    public partial class DashboardTabPage : TabbedPage
    {
        public static readonly BindableProperty IsAndroidLeftNavBarItemVisibleProperty =
            BindableProperty.Create(nameof(IsAndroidLeftNavBarItemVisibleProperty), typeof(bool), typeof(DashboardTabPage), false);

        public bool IsAndroidLeftNavBarItemVisible
        {
            get { return (bool)GetValue(IsAndroidLeftNavBarItemVisibleProperty); }
            set { SetValue(IsAndroidLeftNavBarItemVisibleProperty, value); }
        }

        private bool menuIsOpen = false;
        private int lastSelectedItemIndex;
        public event EventHandler<int> DashboardBadgeEvent;

        public DashboardTabPage()
        {
            InitializeComponent();
            Microsoft.Maui.Controls.PlatformConfiguration.AndroidSpecific.TabbedPage.SetIsSwipePagingEnabled(this, false);

            var navigationService = new NavigationService();

            var alertPage = NavigationService.GetNewPage<AlertsViewModel>();
            ((AlertsViewModel)alertPage.BindingContext).BadgeEvent -= DashboardTabPageBadgeEvent;
            ((AlertsViewModel)alertPage.BindingContext).BadgeEvent += DashboardTabPageBadgeEvent;

            var alertNavigationPage = new NavigationPage(alertPage);
            alertNavigationPage.Title = "AlertsText".Localized();
            alertNavigationPage.IconImageSource = "gui_tab_alerts";
            alertNavigationPage.BarTextColor = (Color)AppHelpers.GetResource("DarkGrey");

            var toolbarItem = new ToolbarItem();
            toolbarItem.Text = "ArchiveText".Localized();
            toolbarItem.IconImageSource = "gui_tool_archive_2";
            toolbarItem.SetBinding(MenuItem.CommandProperty, new Binding("ArchiveListCommand"));
            alertPage.ToolbarItems.Add(toolbarItem);

            alertPage.Disappearing -= AlertPage_Disappearing;
            alertPage.Disappearing += AlertPage_Disappearing;

            alertPage.Appearing -= AlertPage_Appearing;
            alertPage.Appearing += AlertPage_Appearing;

            var menuPage = NavigationService.GetNewPage<AppMenuViewModel>();
            var homePage = NavigationService.GetNewPage<MyTasksViewModel>();

            if(DeviceInfo.Platform == DevicePlatform.Android)
            {
                if (menuPage != null)
                {
                    menuPage.AutomationId = "MenuPageTab";
                    Children.Add(menuPage);
                }

                if (homePage != null)
                {
                    homePage.IconImageSource = "gui_tab_home";
                    homePage.AutomationId = "HomePageTab";
                    Children.Add(homePage);
                }

                if (!MainService.Instance.HideAlertsSection)
                {
                    alertPage.AutomationId = "AlertPageTab";
                    Children.Add(alertNavigationPage);
                }
            }
            else if(DeviceInfo.Platform == DevicePlatform.iOS)
            {
                if (!MainService.Instance.HideAlertsSection)
                {
                    alertPage.AutomationId = "AlertPageTab";
                    Children.Add(alertNavigationPage);
                }

                if (homePage != null)
                {
                    homePage.IconImageSource = "gui_tab_home";
                    homePage.AutomationId = "HomePageTab";
                    Children.Add(homePage);
                }
                
                if (menuPage != null)
                {
                    menuPage.AutomationId = "MenuPageTab";
                    Children.Add(menuPage);
                }
            }

            var indexPage = Children.IndexOf(homePage);

            CurrentPage = Children[indexPage];
            lastSelectedItemIndex = indexPage;

            CurrentPageChanged += (object sender, EventArgs e) =>
            {
                ///adding this make sure alert tab updates on navigating to.
                if (Children.IndexOf(CurrentPage) == 0)
                {
                    var alertsViewModel = alertPage.BindingContext as AlertsViewModel;
                    if (alertsViewModel != null && !alertsViewModel.IsRefreshing)
                        alertsViewModel.RefreshCommand.Execute(null);
                }

                HandleCurrentPageChanged(sender, e);
            };
            NavigationPage.SetHasNavigationBar(this, false);
        }


        private void AlertPage_Appearing(object sender, EventArgs e)
        {
            IsAndroidLeftNavBarItemVisible = false;
        }

        private void AlertPage_Disappearing(object sender, EventArgs e)
        {
            IsAndroidLeftNavBarItemVisible = true;
        }

        public void DashboardTabPageBadgeEvent(object sender, int count)
        {
            DashboardBadgeEvent?.Invoke(null, count);
        }

        void HandleCurrentPageChanged(object sender, EventArgs e)
        {
            var i = Children.IndexOf(CurrentPage);
            Debug.WriteLine("Page No:" + i);

            var menuPageType = NavigationService.GetPageType<AppMenuViewModel>();
            if (CurrentPage.GetType() != menuPageType)
            {
                lastSelectedItemIndex = i;
                return;
            }

            MenuOpenClose(!menuIsOpen);
        }

        public void MenuOpenClose(bool isPresented)
        {
            var masterpage = MainService.HomePage.Value as DashboardMasterPage;

            if (masterpage is DashboardMasterPage)
            {
                FlyoutPage homePage = masterpage;
                homePage.IsPresentedChanged -= HomePageIsPresentedChanged;
                homePage.IsPresentedChanged += HomePageIsPresentedChanged;

                homePage.IsPresented = isPresented;
                menuIsOpen = isPresented;

                CurrentPage = Children[lastSelectedItemIndex];
            }
        }

        void HomePageIsPresentedChanged(object sender, EventArgs e)
        {
            var masterpage = MainService.HomePage.Value as DashboardMasterPage;

            if (masterpage is DashboardMasterPage)
            {
                FlyoutPage homePage = masterpage;
                menuIsOpen = homePage.IsPresented;
            }

            var menuPageType = NavigationService.GetPageType<AppMenuViewModel>();
            var appMenuViewModel = Children.FirstOrDefault(p => p.GetType() == menuPageType)?.BindingContext as AppMenuViewModel;
            if (appMenuViewModel != null)
            {
                appMenuViewModel.IsMenuPresented = menuIsOpen;
            }

            CurrentPage = Children[lastSelectedItemIndex];
        }
    }

The same code was working fine in Xamarin Forms version. Now I am migrating it to MAUI and there I am facing this issue.

Developer technologies | .NET | .NET MAUI
{count} votes

1 answer

Sort by: Most helpful
  1. Tony Dinh (WICLOUD CORPORATION) 3,585 Reputation points Microsoft External Staff
    2025-10-24T04:25:41.36+00:00

    Hello @Sreenivasan, Sreejith !

    The behavior you’re seeing comes from a change in how FlyoutPage manages its lifecycle in .NET MAUI compared to Xamarin.Forms. In Xamarin.Forms, the IsPresented property and navigation stack were more forgiving. In MAUI, however, the flyout lifecycle is stricter, and reassigning CurrentPage while toggling the flyout interrupts the process.

    That’s why your menu opens the first time, but fails to reopen if you’re still on the Dashboard tab — the forced CurrentPage reset cancels the flyout. Once you switch tabs, the state is refreshed, and the menu works again.

    Here are some approaches you can choose to fix it:


    Remove the CurrentPage reset in MenuOpenClose and HomePageIsPresentedChanged

    The main issue is the CurrentPage = Children[lastSelectedItemIndex] line. Removing it usually resolves the problem:

    public void MenuOpenClose(bool isPresented)
    {
        if (MainService.HomePage.Value is DashboardMasterPage masterpage)
        {
            FlyoutPage homePage = masterpage;
            homePage.IsPresentedChanged -= HomePageIsPresentedChanged;
            homePage.IsPresentedChanged += HomePageIsPresentedChanged;
     
            homePage.IsPresented = isPresented;
            menuIsOpen = isPresented;
     
            // CurrentPage = Children[lastSelectedItemIndex]; // Remove this in MAUI
        }
    }
     
    void HomePageIsPresentedChanged(object sender, EventArgs e)
    {
        if (MainService.HomePage.Value is DashboardMasterPage masterpage)
        {
            FlyoutPage homePage = masterpage;
            menuIsOpen = homePage.IsPresented;
        }
     
        var menuPageType = NavigationService.GetPageType<AppMenuViewModel>();
        var appMenuViewModel = Children.FirstOrDefault(p => p.GetType() == menuPageType)?.BindingContext as AppMenuViewModel;
        if (appMenuViewModel != null)
        {
            appMenuViewModel.IsMenuPresented = menuIsOpen;
        }
     
        // CurrentPage = Children[lastSelectedItemIndex]; // Remove this in MAUI
    }
    

    Set FlyoutPage.FlyoutLayoutBehavior

    In MAUI, the default flyout layout can vary by platform. To avoid conflicts, explicitly set it in your DashboardMasterPage:

    FlyoutLayoutBehavior = FlyoutLayoutBehavior.Single;
    

    This ensures the flyout overlays the detail page instead of trying to push it aside.


    Restore the last tab only when needed

    If you still want to return to the last tab after the menu is opened, handle it in HandleCurrentPageChanged instead of forcing it during the flyout toggle:

    void HandleCurrentPageChanged(object sender, EventArgs e)
    {
        var i = Children.IndexOf(CurrentPage);
        var menuPageType = NavigationService.GetPageType<AppMenuViewModel>();
     
        if (CurrentPage.GetType() == menuPageType)
        {
            MenuOpenClose(true);
            // Don’t reset CurrentPage here
        }
        else
        {
            lastSelectedItemIndex = i;
        }
    }
    

    I hope this clears things up!


Your answer

Answers can be marked as 'Accepted' by the question author and 'Recommended' by moderators, which helps users know the answer solved the author's problem.