Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

messagebox for android mono

Response from the user before the function completes AlertDialog.Builder like messagebox but I want to wait until the user answers. How do I do?

            public bool test() 
            { 
                    bool tst=false; 

                    AlertDialog.Builder builder = new AlertDialog.Builder (this); 
                    builder.SetTitle (Android.Resource.String.DialogAlertTitle); 
                    builder.SetIcon (Android.Resource.Drawable.IcDialogAlert); 
                    builder.SetMessage ("message"); 
                    builder.SetPositiveButton ("OK",(sender,e)=>{ 
                            tst=true; 
                    }); 
                    builder.SetNegativeButton ("NO",(sender,e)=>{ 
                            tst=false; 
                    }); 

                    builder.Show(); 

                    return tst; 
            }
like image 495
mcxxx Avatar asked May 22 '12 06:05

mcxxx


3 Answers

Stuart's answer here is correct, but I just wanted to expand a little on it since there still seems to be some confusion and this is an important concept for designing applications.

When you're dealing with things in the UI, such as responding to user input or prompting for information, you never want to block the UI. As such, in situations like these you need to design your code in a way that allows it to be executed asynchronously. As you noticed, in the case of your code sample the function returns right away since it will not wait for the callback to be executed. If it did wait, the UI thread would be blocked and your application would be frozen, which is almost certainly not what you want.

Since I don't have any context for this function call, I'll make up a simple example. Let's say that you wanted to get the return value of the function and write it to the log. Using the synchronous approach you provided, that would look something like this:

bool returnValue = test();

Console.WriteLine(returnValue);

Instead, what I would suggest doing is restructuring the test() method such that it behaves asynchronously. I would rewrite it to look something like this:

public void test(Action<bool> callback)
{
    AlertDialog.Builder builder = new AlertDialog.Builder(this);
    builder.SetTitle(Android.Resource.String.DialogAlertTitle);
    builder.SetIcon(Android.Resource.Drawable.IcDialogAlert);
    builder.SetMessage("message");
    builder.SetPositiveButton("OK", (sender, e) =>
                                    {
                                        callback(true);
                                    });
    builder.SetNegativeButton("NO", (sender, e) =>
                                    {
                                        callback(false);
                                    });

    builder.Show();
}

This version is very similar to yours, except that instead of returning the value directly from the method call, it is sent back via the callback parameter of the method. The code to write out to the log can then be updated to this:

test(returnValue =>
{
    Console.WriteLine(returnValue);
});

I have a blog post up here that also talks about different ways to do work in background threads and display the results in the UI, if that applies to your situation at all. Hope this helps clear things up!

like image 54
Greg Shackles Avatar answered Nov 01 '22 13:11

Greg Shackles


I know this is old, but I have developed a simple helper based on the answers I have found here and there, so I am putting here on the hope that it helps someone. Enjoy..

using System;
using Android.App;
using Android.Content;

namespace MyApp.Helpers
{
    #region Enums
    public enum MessageBoxResult
    {
        None = 0,
        OK,
        Cancel,
        Yes,
        No
    }

    public enum MessageBoxButton
    {
        OK = 0,
        OKCancel,
        YesNo,
        YesNoCancel
    }

    public enum MessageBoxButtonText
    {
        Ok, 
        Cancel, 
        Yes, 
        No
    }

    #endregion

    public static class MessageBoxHelper
    {
        public static void Show(Context context, Action<bool> callback, string messageBoxText, string caption, MessageBoxButton buttonType)
        {
            AlertDialog.Builder alertBuilder = new AlertDialog.Builder(context);
            alertBuilder.SetTitle(caption);
            //builder.SetIcon(Android.Resource.Drawable.IcDialogAlert);
            alertBuilder.SetMessage(messageBoxText);

            switch (buttonType)
            {
                case MessageBoxButton.OK:
                    alertBuilder.SetPositiveButton(MessageBoxButtonText.Ok.ToString(), (sender, e) => callback(true));
                    break;

                case MessageBoxButton.OKCancel:
                    alertBuilder.SetPositiveButton(MessageBoxButtonText.Ok.ToString(), (sender, e) => callback(true));
                    alertBuilder.SetNegativeButton(MessageBoxButtonText.Cancel.ToString(), (sender, e) => callback(false));
                    break;

                case MessageBoxButton.YesNo:
                    alertBuilder.SetPositiveButton(MessageBoxButtonText.Yes.ToString(), (sender, e) => callback(true));
                    alertBuilder.SetNegativeButton(MessageBoxButtonText.No.ToString(), (sender, e) => callback(false));
                    break;
            }
            alertBuilder.Show();
        }

        public static void Show(Context context, string messageBoxText)
        {
             Show(context, delegate(bool b) { }, messageBoxText, "", MessageBoxButton.OK);
        }

        public static void Show(Context context, string messageBoxText, string caption)
        {
            Show(context, delegate(bool b) { }, messageBoxText, caption, MessageBoxButton.OK);
        }
    }
}
like image 41
Has AlTaiar Avatar answered Nov 01 '22 14:11

Has AlTaiar


There's a full sample in https://github.com/xamarin/monodroid-samples/blob/master/ApiDemo/App/AlertDialogSamples.cs from Xamarin

You can't block the code and wait for the answer - you must respond to the answer event instead.

like image 1
Stuart Avatar answered Nov 01 '22 14:11

Stuart