Sreejith Sree
Sreejith Sree

Reputation: 3716

Xamarin Forms: DisplayAlert background tap firing the cancel event

I am using a DisplayAlert like below in my project.

var answer = await DisplayAlert("Alert", "You are invited to join a group, would you like to accept it or not?", "Accept", "Reject");
if (answer)
{
    //accept invitation
}
else
{
    //reject invitation
}

Accept and Reject options are working fine. My problem is Reject option is executing when tapping on the background or device back arrow. Is it has a simple solution other than implementing Rg.Plugins.Popup?

Upvotes: 0

Views: 1499

Answers (2)

adamm
adamm

Reputation: 919

I had a similar request once, and I quickly "solved it" with a workaround like this (using DisplayActionSheet):

bool isActionSelected = false;
while(!isActionSelected)
{
    string action = await DisplayActionSheet ("You are invited to join a group, would you like to accept it or not?", null, null, "Accept", "Reject");
    if (action == "Accept")
    {
        isActionSelected = true;
        //do stuff         
    }
    else if (action == "Reject")
    {
        isActionSelected = true;
        //do stuff         
    }
    else
    {
        isActionSelected = false;
    }
}

This is not suggested, unless you are in a hurry.

So, I would suggest you creating a custom popupView, something like this

            <ContentView x:Name="popupView" BackgroundColor="#C0808080" Padding="10, 0" IsVisible="false" AbsoluteLayout.LayoutBounds="0, 0, 1, 1" AbsoluteLayout.LayoutFlags="All">
                <StackLayout VerticalOptions="Center" HorizontalOptions="Center">
                    <StackLayout Orientation="Vertical" HeightRequest="150" WidthRequest="200" BackgroundColor="White">                        
                        <Label x:Name="myLabel" TextColor="Black" Text="You are invited to join a group, would you like to accept it or not?" />
                        <Button Text="Accept" TextTransform="None" Clicked="AcceptClicked" />
                        <Button Text="Reject" TextTransform="None" Clicked="RejectClicked" />
                    </StackLayout>
                </StackLayout>
            </ContentView>

then in .cs

popupView.IsVisible = true;

when you want this to appear.

Upvotes: 1

ColeX
ColeX

Reputation: 14475

The only solution - Use DependencyService to implement the alert on each platform .

Interface in Forms

 public interface IShowAlertService
    {
        Task<bool> ShowAlert(string title, string message, string ok, string cancel);
    }

Android Implementation

[assembly: Dependency(typeof(ShowAlertService))]
namespace XamarinTableView.Droid
{
    class ShowAlertService : IShowAlertService
    {
        TaskCompletionSource<bool> taskCompletionSource;

        public Task<bool> ShowAlert(string title, string message, string ok, string cancel)
        {
            taskCompletionSource = new TaskCompletionSource<bool>();

            Android.App.AlertDialog.Builder dialog = new AlertDialog.Builder(MainActivity.Instance);
            AlertDialog alert = dialog.Create();
            alert.SetTitle("Title");
            alert.SetMessage("Complex Alert");
            alert.SetButton("OK", (c, ev) =>
            {
                // Ok button click task 
                Console.WriteLine("Okay was clicked");
                taskCompletionSource.SetResult(true);
            });
            alert.SetButton2("CANCEL", (c, ev) => {
                Console.WriteLine("Cancel was clicked");
                taskCompletionSource.SetResult(false);
            });
            alert.Show();

         
            return taskCompletionSource.Task;
        }
    }
}

iOS Implementation

[assembly: Dependency(typeof(ShowAlertService))]
namespace XamarinTableView.iOS
{
    class ShowAlertService : IShowAlertService
    {
        TaskCompletionSource<bool> taskCompletionSource;
        public Task<bool> ShowAlert(string title, string message, string ok, string cancel)
        {
            taskCompletionSource = new TaskCompletionSource<bool>();

            var okCancelAlertController = UIAlertController.Create(title, message, UIAlertControllerStyle.Alert);

            //Add Actions
            okCancelAlertController.AddAction(UIAlertAction.Create(ok, UIAlertActionStyle.Default, alert => { 
                Console.WriteLine("Okay was clicked");
                taskCompletionSource.SetResult(true);
            }));
            okCancelAlertController.AddAction(UIAlertAction.Create(cancel, UIAlertActionStyle.Cancel, alert => { 
                Console.WriteLine("Cancel was clicked");
                taskCompletionSource.SetResult(false);
            }));

            UIWindow window = UIApplication.SharedApplication.KeyWindow;
            var viewController = window.RootViewController;
            //Present Alert
            viewController.PresentViewController(okCancelAlertController, true, null);

            return taskCompletionSource.Task;
        }

}

Consume in Forms

bool isOk = await DependencyService.Get<IShowAlertService>().ShowAlert("Alert", "You have been alerted", "OK", "Cancel");

 if (isOk)
 {

 }
 else
 {

 }

In this way clicking outside the alert will not trigger cancel event .

Refer to DisplayAlert Xamarim forms.

Upvotes: 1

Related Questions