Welcome to OStack Knowledge Sharing Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
1.3k views
in Technique[技术] by (71.8m points)

xamarin.forms - How to intercept Navigation Bar Back Button Clicked in Xamarin Forms?

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 been saved.How to do it?

I'm able to intercept the hardware Bar Back Button Clicked in Android using the Android.MainActivity.OnBackPressed(), but that event is raised only on hardware Bar Back Button Clicked, not on Navigation Bar Back Button Clicked.

I tried also to override Xamarin.Forms.NavigationPageOnBackButtonPressed() but it doesn't work. Why? Any one have already solved that issue?

I also tried by overriding OnDisappear(), there are two problems:

  1. The page has already visually disappeared so the "Are you sure?" dialog appears over the previous page.
  2. Cannot cancel the back action.

So, is it possible to intercept the navigation bar back button press?

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Answer

0 votes
by (71.8m points)

I was able to show a confirmation dialog that could cancel navigation by overriding the following methods in the FormsApplicationActivity.

  // navigation back button
  public override bool OnOptionsItemSelected(IMenuItem item)
  {
     if (item.ItemId == 16908332)
     {
        var currentViewModel = (IViewModel)navigator.CurrentPage.BindingContext;
        currentViewModel.CanNavigateFromAsync().ContinueWith(t =>
        {
           if (t.Result)
           {
              navigator.PopAsync();
           }
        }, TaskScheduler.FromCurrentSynchronizationContext());
        return false;
     }
     else
     {
        return base.OnOptionsItemSelected(item);
     }
  }

  // hardware back button
  public async override void OnBackPressed()
  {
     var currentViewModel = (IViewModel)navigator.CurrentPage.BindingContext;

     // could display a confirmation dialog (ex: "Cancel changes?")
     var canNavigate = await currentViewModel.CanNavigateFromAsync();
     if (canNavigate)
     {
        base.OnBackPressed();
     }
  }

The navigator.CurrentPage is a wrapper around the INavigation service. I do not have to cancel navigation from modal pages so I am only handling the NavigationStack.

this.navigation.NavigationStack[this.navigation.NavigationStack.Count - 1];

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome to OStack Knowledge Sharing Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...