How to show Confirmation Alert dialog before popping a Page in Xamarin.Forms ?

I am developing a cross platform application using Xamarin.Forms.
I have two pages page1 and page2.
When moving from page2 to page1, using Navigation.PopAsync, I need to show an alert dialog to let the user confirm the action. Only after the user confirms, I need to pop the page.
I need to trap the actions of both the 'Home' button as well as the 'Back' button in android.

How can this be done ?

Answers

  • SampathKumarSampathKumar USMember

    But , is it possible to trap the OnOptionsItemSelected event inside a page renderer ?

    We can get the Activity instance using Context of the page inside the renderer. But using that activity instance, can we define the OnOptionsItemSelected method ?

  • RaphaelSchindlerRaphaelSchindler ✭✭✭ USMember ✭✭✭

    I'm not sure I understand what you want.
    Could you show some code of what you're meaning?

  • SampathKumarSampathKumar USMember

    Inside a custom PageRenderer, I can get the current Activity using

    Activity activity = Context as Activity;

    Is there a way, in which I can use this activity instance to define the OnOptionsItemSelected(IMenuItem item) method of the Activity class ?

  • RaphaelSchindlerRaphaelSchindler ✭✭✭ USMember ✭✭✭

    Uhm that should work yes. But you need OptionItems then. The call is activity.OnOptionsItemSelected

  • ahmadmadiahmadmadi ✭✭✭ USMember ✭✭✭
    1. Can you share some code ?
    2. If it is for me to do it , then I would await the popup (Alert) before using Navigation.PopAsync, you can find more information about Popups here
  • SampathKumarSampathKumar USMember

    @ahmadmadi : My motive is to trap the back and home button press. So I have no option of deliberately calling Navigation.PopAsync. It is popped internally on back and home press.

    @RaphaelSchindler : the activity.OnOptionsItemSelected is just a public virtual method and there is no event-delegate mechanism for that , as of now.

  • RaphaelSchindlerRaphaelSchindler ✭✭✭ USMember ✭✭✭

    @SampathKumar If it's virtual then override it like this

    public override bool OnOptionsItemSelected(IMenuItem item)
    {
        return base.OnOptionsItemSelected(item);
    }
    
  • SampathKumarSampathKumar USMember

    @RaphaelSchindler : Inside a Page renderer, I believe we cant override it, though we can get the activity instance.

  • RaphaelSchindlerRaphaelSchindler ✭✭✭ USMember ✭✭✭

    Ah yes you're right. Haven't tested it in a PageRenderer, just in MainActivity.cs. Maybe you can achive what you wan't with the defined stuff in App.cs

  • SampathKumarSampathKumar USMember
    edited September 2015

    I finally got a way around to show alert on pressing home..

    I had only one Activity in my application. So inside my Activity.cs,

    `public override bool OnOptionsItemSelected (IMenuItem item)
    {
    if (Android.Resource.Id.Home != item.ItemId)
    return base.OnOptionsItemSelected (item);

            OnBackPressed (); // This calls the OnBackButtonPressed method of the current page.
    
            return true;
    
        }`
    

    Then inside, the OnBackButtonPressed of my 'Page' I had a check as you mentioned, to show an alert.

    Previously I was believing that the 'OnBackButtonPressed' callback for a page precedes the OnBackPressed of the activity.
    But it seems , it is the other way around.
    OnBackButtonPressed is called only after the OnBackPressed of the activity.

    This is the reason why OnBackButtonPressed is not called when we tap the home button in a page.

  • ManojkumarMaliManojkumarMali ✭✭✭ USMember ✭✭✭
    edited February 2017

    This works for me..

    protected override bool OnBackButtonPressed() { Device.BeginInvokeOnMainThread(async() => { var result = await this.DisplayAlert("Alert!", "Do you really want to exit?", "Yes", "No"); if (result) await this.Navigation.PopAsync(); // or anything else }); return true; }

  • EswaranEswaran ✭✭ INMember ✭✭

    @ManojkumarMali
    How can i apply Device.BeginInvokeOnMainThread(async() => {
    var result = await this.DisplayAlert("Alert!", "Do you really want to exit?", "Yes", "No");
    if (result) await this.Navigation.PopAsync(); // or anything else
    });
    in " OnDisappearing()" method ?

  • ManojkumarMaliManojkumarMali ✭✭✭ USMember ✭✭✭

    @Eswaran
    You can make a use of OnBackButtonPressed event.

    There is no use of Disappearing event, because it called when page disappears.

  • EswaranEswaran ✭✭ INMember ✭✭

    @ManojkumarMali
    thanks for your reply.
    OnBackButtonPressed event is called only when we click the hardware back button is clicked. Actually I need to display a alert message when i click the Navigation bar back button(i.e. software back button). For Navigation bar back button the OnBackButtonPressed event is not called instead OnDisappearing event is called where i cant able to perform async function.

  • AmolKAmolK ✭✭ INMember ✭✭

    @ManojkumarMali
    Thanks, It works for me.
    You saved my Day.

  • Curtis_HerrickCurtis_Herrick ✭✭ Member ✭✭

    Has anyone figured out how to intercept the navigation back button (not the hardware back button) being tapped on the navigation bar so that one can ask the user if they really want to exit/pop the page?

    Navigation offers the Popped event to hook into, which is great for view/viewmodel cleanup, but I believe it's too late to be asking at that point whether they really want to close the page. Ideas?

  • JoeMankeJoeManke ✭✭✭✭✭ USMember ✭✭✭✭✭

    What I do in cases like that is push the page modally, and add a Cancel toolbar item. You can get confirmation before popping the modal page in both OnBackButtonPressed and the toolbar item click handler, and there will be no back button in the navigation bar.

Sign In or Register to comment.