c# Xamarin Android return 来自 AlertDialog 的响应布尔

c# Xamarin Android return response bool from AlertDialog

我正在尝试 return 如果用户从 AlertDialog 中选择是,则布尔值为真,反之亦然。

目前它总是 return 错误。似乎从未设置 bool "result"。

public bool AskForConfirmation(string messege, Context context)
{
    bool result;

    Android.Support.V7.App.AlertDialog.Builder dialog = new Android.Support.V7.App.AlertDialog.Builder(context);

    dialog.SetPositiveButton("Yes", (sender, args) =>
    {
        result = true;
    });

    dialog.SetNegativeButton("No", (sender, args) =>
    {
        result = false;
    }).SetMessage(messege).SetTitle("System Message");


    dialog.Show();

    return result;
}

我调用方法

this.RunOnUiThread(() =>
{

    bool response = ioManager.AskForConfirmation("Message", this);

    Console.WriteLine("Response is " + response);

});

您可以通过 ManualResetEventTaskCompletionSource 创建一个基于 Task 的对话框,这样您就可以这样调用它:

通过 TaskCompletionSource 示例的用法:

try
{
    var result = await DialogAsync.Show(this, "Whosebug", "Does it rock?");
    Log.Debug("SO", $"Dialog result: {result}");
}
catch (TaskCanceledException ex)
{
    Log.Debug("SO", $"Dialog cancelled; backbutton, click outside dialog, system-initiated, .... ");
}

通过 TaskCompletionSource 示例的 DialogAsync:

public class DialogAsync : Java.Lang.Object, IDialogInterfaceOnClickListener, IDialogInterfaceOnCancelListener
{
    readonly TaskCompletionSource<bool?> taskCompletionSource = new TaskCompletionSource<bool?>();

    public DialogAsync(IntPtr handle, Android.Runtime.JniHandleOwnership transfer) : base(handle, transfer) { }
    public DialogAsync() { }

    public void OnClick(IDialogInterface dialog, int which)
    {
        switch (which)
        {
            case -1:
                SetResult(true);
                break;
            default:
                SetResult(false);
                break;
        }
    }

    public void OnCancel(IDialogInterface dialog)
    {
        taskCompletionSource.SetCanceled();
    }

    void SetResult(bool? selection)
    {
        taskCompletionSource.SetResult(selection);
    }

    public async static Task<bool?> Show(Activity context, string title, string message)
    {
        using (var listener = new DialogAsync())
        using (var dialog = new AlertDialog.Builder(context)
                                                            .SetPositiveButton("Yes", listener)
                                                            .SetNegativeButton("No", listener)
                                                            .SetOnCancelListener(listener)
                                                            .SetTitle(title)
                                                            .SetMessage(message))
        {
            dialog.Show();
            return await listener.taskCompletionSource.Task;
        }
    }
}

通过 ManualResetEvent 示例的用法:

using (var cancellationTokenSource = new CancellationTokenSource())
{
    var result = await DialogAsync.Show(this, "Whosebug", "Does it rock?", cancellationTokenSource);
    if (!cancellationTokenSource.Token.IsCancellationRequested)
    {
        Log.Debug("SO", $"Dialog result: {result}");
    }
    else
    {
        Log.Debug("SO", $"Dialog cancelled; backbutton, click outside dialog, system-initiated, .... ");
    }
}

DialogAsync 通过 ManualResetEvent 示例:

public class DialogAsync : Java.Lang.Object, IDialogInterfaceOnClickListener, IDialogInterfaceOnCancelListener
{
    readonly ManualResetEvent resetEvent = new ManualResetEvent(false);
    CancellationTokenSource cancellationTokenSource;
    bool? result;

    public DialogAsync(IntPtr handle, Android.Runtime.JniHandleOwnership transfer) : base(handle, transfer) { }
    public DialogAsync() { }

    public void OnClick(IDialogInterface dialog, int which)
    {
        switch (which)
        {
            case -1:
                SetResult(true);
                break;
            default:
                SetResult(false);
                break;
        }
    }

    public void OnCancel(IDialogInterface dialog)
    {
        cancellationTokenSource.Cancel();
        SetResult(null);
    }

    void SetResult(bool? selection)
    {
        result = selection;
        resetEvent.Set();
    }

    public async static Task<bool?> Show(Activity context, string title, string message, CancellationTokenSource source)
    {
        using (var listener = new DialogAsync())
        using (var dialog = new AlertDialog.Builder(context)
                                                            .SetPositiveButton("Yes", listener)
                                                            .SetNegativeButton("No", listener)
                                                            .SetOnCancelListener(listener)
                                                            .SetTitle(title)
                                                            .SetMessage(message))
        {
            listener.cancellationTokenSource = source;
            context.RunOnUiThread(() => { dialog.Show(); });
            await Task.Run(() => { listener.resetEvent.WaitOne(); }, source.Token);
            return listener.result;
        }
    }
}