How to intercept Navigation Bar Back Button Clicked in Xamarin Forms?

前端 未结 6 1623
死守一世寂寞
死守一世寂寞 2020-12-07 00:41

I have a xamarin form page where a user can update some data in a form. I need to intercept the Navigation Bar Back Button Clicked to warn the user if some data have not bee

6条回答
  •  一向
    一向 (楼主)
    2020-12-07 01:08

    Best way I have found is adding my own NavigationRenderer to intercept the navigation methods and a simple Interface

    [assembly: ExportRenderer(typeof(NavigationPage), typeof(CustomerMobile.Droid.NavigationPageRenderer))]
    
    public class NavigationPageRenderer : Xamarin.Forms.Platform.Android.AppCompat.NavigationPageRenderer
    {
        public Activity context;
    
        public NavigationPageRenderer(Context context)
            : base(context)
        {}
    
        protected override Task OnPushAsync(Page page, bool animated) {...}
    
        protected override Task OnPopToRootAsync(Page page, bool animated){...}
    
        protected override Task OnPopViewAsync(Page page, bool animated)
        {
            // if the page implements my interface then first check the page 
            //itself is not already handling a redirection ( Handling Navigation) 
            //if don't then let the handler to check whether to process 
            // Navitation or not . 
            if (page is INavigationHandler handler && !handler.HandlingNavigation
                 && handler.HandlePopAsync(page, animated))
                return Task.FromResult(false);
            
            return base.OnPopViewAsync(page, animated);
        }
    }
    

    Then my INavigationHandler interface would look like this

    public interface INavigationHandler
    {
        public bool HandlingNavigation { get; }
        public bool HandlePopAsync(Xamarin.Forms.Page view, bool animated);
        public bool HandlePopToRootAsync(Xamarin.Forms.Page view, bool animated);
        public bool HandlePuchAsync(Xamarin.Forms.Page view, bool animated);
    }
    

    Finally in any ContentView, in this example when trying to navigate back I'm just collapsing a menu and preventing a navigation back.

    public partial class MenusList : INavigationHandler
    {
        public bool HandlingNavigation { get; private set; }
    
        public bool HandlePopAsync(Page view, bool animated)
        {
            HandlingNavigation = true;
            try 
            {
                if (Menu.Expanded)
                {
                    Menu.Collapse();
                    return true;
                }
                else return false;
            }
            finally
            {
                HandlingNavigation = false;
            }
        }
    }
    

提交回复
热议问题