简体   繁体   中英

DisplayAlert methods only executed at the end of the method in Xamarin

I'm writing a small Xamarin.Forms app and I try to do some actions like display alerts or show the Activity Indicator. However, everything what I wrote in my code is only executed at the end of the method, even the Activity Indicator, which is not the goal of course. The different alerts are even showing in LIFO, so the last one in the code appears first.

Here's the code in xaml.cs:

    private void btConnexion_Clicked(object sender, EventArgs e)
    {
        ai.IsRunning = true;
        IsBusy = true;
        LoginViewModel vm = (LoginViewModel)this.BindingContext;
        DisplayAlert(AppResources.Sorry, "Beginning", "Ok");

        try
        {
            DisplayAlert(AppResources.Sorry, "In the try", "Ok");

            if (vm.Valide())
            {
                Task t = Task.Run(async () => { await vm.AuthentificationAPI(); });
                if (!t.Wait(TimeSpan.FromSeconds(5)))
                {
                    DisplayAlert(AppResources.Sorry, AppResources.TryAgainLater, "Ok");
                }

                if (t.IsCompleted)
                {
                    GetAllData();
                    Application.Current.MainPage = new AppShell();
                    Shell.Current.GoToAsync("//main");

                }
            }
            else
                DisplayAlert(AppResources.Error, AppResources.MissingFieldsErrorMessage, "Ok");

        }
        catch (Exception ex)
        {
            DisplayAlert(AppResources.Sorry, AppResources.TryAgainLater + " (" + ex.Message + ")", "Ok");
        }
        finally
        {
            ai.IsRunning = false;
            DisplayAlert(AppResources.Sorry, "Finally", "Ok");


        }
        DisplayAlert(AppResources.Sorry, "After finally", "Ok");
    }

And where I call it in the .xaml:

        <Button Text="{x:Static resource:AppResources.Login}" 
                x:Name="btConnexion" 
                BackgroundColor="#AADC14" 
                Padding="0,0,0,0" 
                Clicked="btConnexion_Clicked"/>

I've put some alerts in the metohd, showing "In the try,", "Beginning", etc. If I debug the code step by step, all the alerts are only executed once at the end of the method, instead during the compilation. And in FILO, so the first one is "After finally", then "Finally", etc. And the Activity Indicator is not even showing, because of the same reason I suppose.

I don't know if it changes anything, but the xaml must be compiled as written in xaml.cs:

[XamlCompilation(XamlCompilationOptions.Compile)]
public partial class LoginPage : ContentPage

将 await 放在显示警报之前,如下所示

await DisplayAlert ("Alert", "You have been alerted", "OK");

I created a small instance to change the internal state of the DisplayAlert and ActivityIndicator methods.

Here is cs code:

public partial class MainPage : ContentPage
{
    public MainPage()
    {
        InitializeComponent();
    }

    //For DisplayAlert you only need to add await before the method.
    private async void btConnexion_Clicked(object sender, EventArgs e)
    {
        if ((sender as Button).Text == "test") 
        {
            await DisplayAlert("sorry", "try again later", "Ok");  
        }          
        await DisplayAlert("end", "end", "Ok");
    }

    //For ActivityIndicator, I use Task.Delay to make the effect clearer
    private async void Button_Clicked(object sender, EventArgs e)
    {
        ActivityIndicator indicator = new ActivityIndicator();
        indicator.IsRunning = true;
        indicator.IsVisible = true;
        indicator.Color = Color.Black;
        stacklayout.Children.Add(indicator);
        await Task.Delay(3000);
        indicator.IsRunning = false;
        indicator.IsVisible = false;
    }
}

Here is xaml code:

<StackLayout x:Name="stacklayout">
    <Button Text="test" 
            x:Name="btConnexion" 
            BackgroundColor="#AADC14" 
            Padding="0,0,0,0" 
            Clicked="btConnexion_Clicked"/>
    <Button Text="ActivityIndicator" Clicked="Button_Clicked"></Button>
</StackLayout>

Finally the problem was solved by putting the Activity Indicator at the end of the GridView, instead of the beginning, as below. So the AI was there, but not visible, because hidden in the background by the AbsoluteLayout.

</AbsoluteLayout>

<ActivityIndicator 
    IsRunning="{Binding IsBusy}"
    IsVisible="{Binding IsBusy}"
    Color="Red"
    VerticalOptions="CenterAndExpand" 
    HorizontalOptions="CenterAndExpand" 
    />

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM