Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

await for a PushModalAsync form to closed in xamarin forms

I have a page and on clicking a plus button on toolbar i am calling a popup page

from popup page user can add a new entry or cancel / close window without doing anything

Everything is working fine and code is like this

    public partial class SelectSchool : ContentPage
    {
        public SelectSchool()
        {
            InitializeComponent();
            #region toolbar
            ToolbarItem tbi = null;
            if (Device.OS == TargetPlatform.Android)
            {
                tbi = new ToolbarItem("+", "plus", async () =>
                {
                    var target_page = new AddSchool(); 
                    Navigation.PushModalAsync(target_page);                                 
                }, 0,0);
            }
            ToolbarItems.Add(tbi);
            #endregion

            this.Title = "Select School";

        }
    }

And my popup page is like

     public partial class AddSchool : ContentPage
    {
        public AddSchool()
        {
            InitializeComponent();
        }
        private async void Button_OK_Clicked(object sender, EventArgs e)
        {
        //doing some operations like entry to db etc and close page
             Navigation.PopModalAsync();

        }
        private void cancelClicked(object sender, EventArgs e)
        {
            Navigation.PopModalAsync();
        }
    }

But now i want to wait for the Popup to get closed to do some additional coding and i tried below code

 if (Device.OS == TargetPlatform.Android)
            {
                tbi = new ToolbarItem("+", "plus", async () =>
                {
                    var target_page = new AddSchool(); 
                    await Navigation.PushModalAsync(target_page);  
                    //await till target_page is closed and once its closed call my next function here               
                }, 0,0);
            }

But await is not working . How can i await on this area till the popup getting closed ? Any idea??

like image 405
Sebastian Avatar asked Sep 23 '16 04:09

Sebastian


2 Answers

Use the Disappearing event on your modal page.

Example:

var modalPage = new ContentPage();
modalPage.Disappearing += (sender2, e2) =>
{
    System.Diagnostics.Debug.WriteLine("The modal page is dismissed, do something now");
};
await content.Navigation.PushModalAsync(modalPage);
System.Diagnostics.Debug.WriteLine("The modal page is now on screen, hit back button");

Or use a EventWaitHandle:

var waitHandle = new EventWaitHandle(false, EventResetMode.AutoReset);
var modalPage = new ContentPage();
modalPage.Disappearing += (sender2, e2) =>
{
    waitHandle.Set();
};
await content.Navigation.PushModalAsync(modalPage);
System.Diagnostics.Debug.WriteLine("The modal page is now on screen, hit back button");
await Task.Run(() => waitHandle.WaitOne());
System.Diagnostics.Debug.WriteLine("The modal page is dismissed, do something now");
like image 196
SushiHangover Avatar answered Sep 30 '22 10:09

SushiHangover


A bit late on the answer here, but it might be best to listen to the Application's OnModalPagePopping event handler.

First, create the modal page. Give it a property to store the data you want to later retrieve:

public class MyModalPage : ContentPage
{
    public string Data { get; set; }

    public MyModalPage()
    {
        InitializeComponent();
        // ... set up the page ...
    }

    private async void PopThisPage()
    {
        // When you want to pop the page, just call this method
        // Perhaps you have a text view with x:Name="PhoneNumber", for example
        Data = PhoneNumber.Text; // store the "return value" before popping
        await MyProject.App.Current.MainPage.Navigation.PopModalAsync();
    }
}

In the parent page, you can create the modal page, and set up the event handler to listen for when the modal page pops:

public class MyPage : ContentPage
{
    MyModalPage _myModalPage;

    public MyPage()
    {
        InitializeComponent();
        // ... set up the page ...
    }

    private async void ShowModalPage()
    {
        // When you want to show the modal page, just call this method
        // add the event handler for to listen for the modal popping event:
        MyProject.App.Current.ModalPopping += HandleModalPopping;
        _myModalPage = new MyModalPage();
        await MyProject.App.Current.MainPage.Navigation.PushModalAsync(_myModalPage());
    }

    private void HandleModalPopping(object sender, ModalPoppingEventArgs e)
    {
        if (e.Modal == _myModalPage)
        {
            // now we can retrieve that phone number:
            var phoneNumber = _myModalPage.Data;
            _myModalPage = null;

            // remember to remove the event handler:
            MyProject.App.Current.ModalPopping -= HandleModalPopping;
        }
    }

}

This is better than using the OnDisappearing method, as others have already stated that can be called when the app is backgrounded, etc. And its behavior is not consistent across platforms.

There is also another event OnModalPopped, which is called after the modal is completely popped from the navigation stack. If using that, it should work similarly.

like image 36
sme Avatar answered Sep 30 '22 09:09

sme