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<bool> OnPushAsync(Page page, bool animated) {...}
protected override Task<bool> OnPopToRootAsync(Page page, bool animated){...}
protected override Task<bool> 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;
}
}
}