Xamarin/Android -创建一个像MessageBox一样等待的模态窗口.从c# . net中显示

本文关键字:窗口 模态 等待 显示 一样 net MessageBox Android 创建 Xamarin 一个 | 更新日期: 2023-09-27 18:12:21

我一直致力于将一个客户端应用程序从。net WinForms移植到Android,我遇到了一个问题,需要在继续之前等待用户交互的对话框。

我现在就说,前面。虽然我对Android比较陌生,但我知道这在Android中是不受欢迎的,因为它会影响UI线程。我理解这一点,然而,他们明确地告诉我,他们希望以同样的方式在。net上工作,我不明白异步方法和回调如何允许我在不大规模重新组织他们的例程(违背他们的意愿)的情况下做到这一点。因此,就这个问题的目的而言,一般理想的方式对我来说不是一个选择。

我尝试了一些不同的方法来达到我想要的结果,没有什么是100%的。我很接近这个:

public class MessageBox
{
    public class mHandler : Handler
    {
        public override void HandleMessage(Message mesg)
        {
            throw new MessageBoxException();
        }
    }
    public class MessageBoxException : Exception
    {
        public MessageBoxException()
        {
        }
        public MessageBoxException(string message)
            : base(message)
        {
        }
        public MessageBoxException(string message, Exception inner)
            : base(message, inner)
        {
        }
    }
    public enum MessageBoxResult
    {
        Positive, Negative, Ignore, Cancel, Closed
    };
    private static Handler handler;
    private static MessageBoxResult yesNoDialogResult;
    public static MessageBoxResult Show(Context context, String title, String message, String positiveMessage, String negativeMessage)
    {
        yesNoDialogResult = MessageBoxResult.Closed;
        AlertDialog.Builder alert = new AlertDialog.Builder(context);
        alert.SetTitle(title);
        alert.SetMessage(message);
        alert.SetCancelable(false);
        alert.SetIcon(Android.Resource.Drawable.IcDialogAlert);
        handler = new mHandler();
        alert.SetPositiveButton("OK", (senderAlert, args) =>
        {
            yesNoDialogResult = MessageBoxResult.Positive;
            handler.SendMessage(handler.ObtainMessage());
        });
        alert.SetNegativeButton("Cancel", (senderAlert, args) =>
        {
            yesNoDialogResult = MessageBoxResult.Negative;
            handler.SendMessage(handler.ObtainMessage());
        });
        alert.Show(); 
        try { Looper.Loop(); }
        catch (MessageBoxException exc) { }
        return yesNoDialogResult;
    }
}

我创建了一个带有Show()的MessageBox类。为了让它等待,我使用一个自定义Handler和主loop来触发一个自定义Exception,然后处理它。

在运行时,这一切都工作得很好。然而,我遇到的问题是,当我使用Visual Studio 2013调试我的应用程序时,当我抛出异常时,它总是会中断。

为了解决这个问题,我试着改变我的异常设置,使其在自定义异常时永远不会中断,但无济于事。我也试过使用System.Diagnostics。DebuggerHidden]来绕过调试错误,但所完成的只是将它失败的点从Show或Handler内部移动到当我试图使用它时。Show()方法调用。

如果有人能给我指出正确的方向,无论是修复这个,或另一个可行的解决方案,我将非常感激。

Xamarin/Android -创建一个像MessageBox一样等待的模态窗口.从c# . net中显示

使用EventWaitHandle使AlertDialog "modal":

public class MessageBox
{
    public enum MessageBoxResult
    {
        Positive, Negative, Ignore, Cancel, Closed
    };
    private static MessageBoxResult yesNoDialogResult;
    public static async Task<MessageBoxResult> Show(Context context, String title, String message, String positiveMessage, String negativeMessage)
    {
        yesNoDialogResult = MessageBoxResult.Closed;
        var alert = new AlertDialog.Builder(context)
           .SetTitle(title).SetMessage(message)
           .SetCancelable(false)
           .SetIcon(Android.Resource.Drawable.IcDialogAlert);
        var waitHandle = new EventWaitHandle(false, EventResetMode.AutoReset);
        alert.SetPositiveButton("OK", (senderAlert, args) =>
        {
            yesNoDialogResult = MessageBoxResult.Positive;
            waitHandle.Set();
        });
        alert.SetNegativeButton("Cancel", (senderAlert, args) =>
        {
            yesNoDialogResult = MessageBoxResult.Negative;
            waitHandle.Set();
        });
        alert.Show();
        await Task.Run(() => waitHandle.WaitOne());
        return yesNoDialogResult;
    }
}

用法:

button.Click += async delegate { 
    Console.WriteLine("MessageBox.Show");
    var answer = await MessageBox.Show(this, "Stack", "Overflow", "", "");
    Console.WriteLine(answer);
};