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