Xamarin Android - 从OnOptionsItemSelected()调用确认对话框弹出窗口

时间:2017-03-23 21:35:31

标签: c# xamarin.android async-await android-alertdialog android-toolbar

我在Android平台上使用Xamarin,C#,当用户点击顶部操作栏中的图标时,需要弹出是/否确认对话框。 假设此图标应触发表中的“删除所有行”,操作需要用户确认。

我应该如何实现此自定义对话框弹出窗口并获得用户的选择? 有什么实际的例子吗?

以下代码来自我的MainActivity:ActionBarActivity,以下代码无法按预期工作。 没有显示弹出对话框,几秒钟后应用程序停止响应。

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;
}

1 个答案:

答案 0 :(得分:0)

您已经评论了等待用户选择选项的代码,因此响应将始终为空。以这种方式更改您的代码:

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;
}

然后,实现异步助手from here以同步执行任务:

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

需要使用帮助程序是因为如果Wait()的任务结束将阻止de UI线程,因为UI线程负责显示对话框,那么将会出现死锁,应用程序将挂起。