GigelPopescu
GigelPopescu

Reputation: 31

Xamarin Android - call a Confirmation Dialog popup from OnOptionsItemSelected()

I am using Xamarin, C#, on Android platform, and need to popup a Yes/No confirmation dialog when the user clicks an icon from my top action bar. Let's say this icon should trigger a "delete all rows" from a table, and the operation requires user's confirmation.

How should I implement this custom dialog popup and get user's choice? Any working example?

The following code is from my MainActivity : ActionBarActivity, and the following code does not work as expected. No popup dialog is displayed, and the app stops responding after a few seconds.

public override bool OnOptionsItemSelected(IMenuItem item)
{
    var res = OnOptionsItemSelectedAsync(item);

    if (res.Result) return true;
    else return false;
}

public async Task<bool> OnOptionsItemSelectedAsync(IMenuItem item)
{
    var tcs = new TaskCompletionSource<bool>();
    tcs.SetResult(true);

    switch (item.ItemId)
    {
        case Resource.Id.action_delete:
            // Show Yes/No confirmation dialog here, blocking (sync)
            string dialogResponse = await DisplayCustomDialog("Confirm delete", "Are you sure you want to delete all rows?", "YES", "NO");
            //string dialogResponse = DisplayCustomDialog("Confirm delete", "Are you sure you want to delete all rows?", "YES", "NO");
            if ("YES" == dialogResponse)
            {
                //...
                Toast.MakeText(this, "Deleted!", ToastLength.Short).Show();
            }
            break;
        //...
        default: break;
    }
    return tcs.Task.Result;
}

private Task<string> DisplayCustomDialog(string dialogTitle, string dialogMessage, string dialogPositiveBtnLabel, string dialogNegativeBtnLabel)
{
    var tcs = new TaskCompletionSource<string>();

    Android.App.AlertDialog.Builder alert = new Android.App.AlertDialog.Builder(this);
    alert.SetTitle(dialogTitle);
    alert.SetMessage(dialogMessage);
    alert.SetPositiveButton(dialogPositiveBtnLabel, (senderAlert, args) => {
        //Toast.MakeText(this, dialogPositiveBtnLabel + "!", ToastLength.Short).Show();
        tcs.SetResult(dialogPositiveBtnLabel);
    });
    alert.SetNegativeButton(dialogNegativeBtnLabel, (senderAlert, args) => {
        //Toast.MakeText(this, dialogNegativeBtnLabel + "!", ToastLength.Short).Show();
        tcs.SetResult(dialogNegativeBtnLabel);
    });
    Dialog dialog = alert.Create();
    dialog.Show();

    // Test with DisplayAlert()
    //var answer = await DisplayAlert(dialogTitle, dialogMessage, dialogPositiveBtnLabel, dialogNegativeBtnLabel);
    //Debug.WriteLine("Answer: " + answer);

    return tcs.Task;
}

Upvotes: 1

Views: 8300

Answers (1)

Gusman
Gusman

Reputation: 15151

You have commented the code which waited for the user to choose an option, so response will be always empty. Change your code this way:

private Task<string> DisplayCustomDialog(string dialogTitle, string dialogMessage, string dialogPositiveBtnLabel, string dialogNegativeBtnLabel)
{
    var tcs = new TaskCompletionSource<string>();

    Android.App.AlertDialog.Builder alert = new Android.App.AlertDialog.Builder(this);
    alert.SetTitle(dialogTitle);
    alert.SetMessage(dialogMessage);
    alert.SetPositiveButton(dialogPositiveBtnLabel, (senderAlert, args) => {
        tcs.SetResult(dialogPositiveBtnLabel);
    });

    alert.SetNegativeButton(dialogNegativeBtnLabel, (senderAlert, args) => {
        tcs.SetResult(dialogNegativeBtnLabel);
    });

    Dialog dialog = alert.Create();
    dialog.Show();

    return tcs.Task;
}

Then, implement the async helper from here to execute a task synchronously:

string dialogResponse = AsyncHelpers.RunSync<string>(() => DisplayCustomDialog("Confirm delete", "Are you sure you want to delete all rows?", "YES", "NO"));

The need to use the helper is because if you Wait() for the task to end that will block de UI thread, as the UI thread is the one responsible on showing the dialog then there will be a deadlock and the app will hang.

Upvotes: 3

Related Questions