I've been working on porting an application to Android from .NET WinForms for a client, and I have run into a snag with a requirement for Dialogs that wait for user interaction before continuing.
I'll say this now, up front. While I'm relatively new to Android, I am aware that this is frowned upon in Android because of impacts on the UI thread. I understand this, however, I've been told in no uncertain terms they want it the same way it works on .NET and I fail to see how async methods and callbacks will allow me to do that without massively re-organizing their routines (against, their wishes). So, for the purpose of this question, doing it the generally ideal way is not an option for me.
I have tried some different options to achieve the result I want, nothing has been 100%. I am close though with this:
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;
}
}
I have created a MessageBox class with a Show(). To make it wait, I am using a custom Handler and the main Looper to trigger a custom Exception, which I am then handling.
At runtime, this all works, quite well actually. The problem I'm having however is that when I debug my application using Visual Studio 2013, it always breaks when I throw my exception.
To combat this, I've tried changing my Exception settings to never break on my custom exception, to no avail. I've also tried the use of [System.Diagnostics.DebuggerHidden] to bypass debugging the error, but all that accomplished was moving the point where it fails from inside the Show or Handler to instead the .Show() method call when I tried to use it.
If anyone can point me in the right direction here for either a fix to this, or another workable solution, I would be extremely grateful.