Xamarin.Forms Page.DisplayAlert dans Page.OnAppearing


Bondoline

Je ne parviens pas à DisplayAlertafficher une fenêtre contextuelle dans le OnAppearingrappel d'un Xamarin.Forms Page. Voici ce que j'ai essayé jusqu'à présent :

protected override void OnAppearing()
{
    base.OnAppearing();

    this.DisplayAlert("Alert", "Consider yourself alerted", "OK");
}

Considérant qu'il DisplayAlerts'agit techniquement d'une asyncfonction, renvoyant un Task, j'ai également essayé ce qui suit :

protected async override void OnAppearing()
{
    base.OnAppearing();

    await this.DisplayAlert("Alert", "Consider yourself alerted", "OK");
}

Cependant, ni l'un ni l'autre ne semble fonctionner. Je suppose que cela n'a pas vraiment de sens de faire OnAppearingcomme étant asyncdu tout, car il ne renvoie pas un Task, et cela se transforme donc en une situation de feu et d'oubli en ce qui concerne le cadre d'appel. Il en va de même par extension DisplayAlertdans ce contexte. Donc , d'une part , je ne pense pas vraiment que cela fonctionne du tout, mais si je me trompe, est - il possible d'utiliser DisplayAlertdans OnAppearing?

Mettre à jour

Il semble que je n'ai pas réussi à fournir un certain contexte. Je travaille à partir d'un modèle Shell Xamarin.Forms ; bien que j'en ai déjà développé quelques-uns après le modèle initial, il est donc difficile de dire à ce stade dans quelle mesure le Shell lui-même y contribue. De plus, ma plate-forme cible principale est Android.

Cela étant dit, j'ai pu démarrer un modèle d'application vierge et essayer le code ci-dessus dans le code autrement frais MainPage- les deux ont bien fonctionné. Je ne sais toujours pas pourquoi ils ne fonctionnent pas dans mon contexte d'application réel, je vais donc creuser là-bas et rendre compte de toutes les conclusions.

Bondoline

J'ai poussé ma petite expérience un peu plus loin et j'ai essayé l'application de modèle Shell de base.

L'ajout de l'exemple de DisplayAlertcode OP au code principal principal ItemsPagen'a pas fonctionné. Si j'ai fait ça,

protected async override void OnAppearing()
{
    base.OnAppearing();

    if (viewModel.Items.Count == 0)
        viewModel.LoadItemsCommand.Execute(null);

    await this.DisplayAlert("Alert", "Consider yourself alerted", "OK");
}

les éléments se chargeraient mais aucune boîte de dialogue ne s'afficherait. Si à la place j'ai déplacé la boîte de dialogue vers le haut,

protected async override void OnAppearing()
{
    base.OnAppearing();

    await this.DisplayAlert("Alert", "Consider yourself alerted", "OK");

    if (viewModel.Items.Count == 0)
        viewModel.LoadItemsCommand.Execute(null);
}

la boîte de dialogue ne s'afficherait pas et les éléments ne se chargeraient pas. Ainsi, l'exécution asynchrone est morte et/ou s'est égarée dans le grand seau dans le ciel.

J'ai ensuite essayé d'ajouter l' DisplayAlertéchantillon à la AppShellpage principale , seulement pour constater que le OnAppearingremplacement n'est pas du tout appelé pour la Shellclasse. Cela a été confirmé par le problème Shell ouvert suivant : [Bug] Shell - OnAppearing n'exécute pas #6486 .

Enfin, juste pour finir, j'ai essayé de pirater un appel à DisplayAlertdans le rappel asynchrone exécuté par LoadItemsCommandin ItemsPage.OnAppearing. Un peu méchant car cela passe la vue dans le modèle de vue, ce qui va directement à l'encontre du bon MVVM en premier lieu --

async Task ExecuteLoadItemsCommand(ItemsPage view)
{
    if (IsBusy)
        return;

    IsBusy = true;

    try
    {
        Items.Clear();
        var items = await DataStore.GetItemsAsync(true);
        foreach (var item in items)
        {
            Items.Add(item);
        }

        await Device.InvokeOnMainThreadAsync(async () =>
            await view.DisplayAlert("Alert", "Consider yourself alerted", "OK"));
    }
    catch (Exception ex)
    {
        Debug.WriteLine(ex);
    }
    finally
    {
        IsBusy = false;
    }
}

Ne me lapide pas.

Cela ne semblait pas avoir de meilleurs résultats. Tout comme lors de l'appel DisplayAlertdirect dans la page OnAppearing, l'exécution a juste pris une pause déjeuner. Le spinner lié au IsBusydrapeau ne s'est jamais arrêté, ce qui indique que le finallybloc n'a même jamais été exécuté.

Ma compréhension générale à ce stade est qu'il existe actuellement une certaine limitation dans le type d'opérations asynchrones qui peuvent être effectuées à partir d'un shell ContentPage. Même l' awaitappel ed à DataStore.GetItemsAsyncn'est pas vraiment asynchrone dans cette implémentation, donc je doute un peu que cela fonctionnerait réellement avec une connexion réelle et asynchrone à la base de données. J'ai pu DisplayAlerttravailler dans le contexte d'un gestionnaire d'événements normal, donc je pense que le problème est limité à la logique d'initialisation qui se déroule pendant OnAppearinget à tout ce qu'il finit par appeler ou planifier directement. Une grande partie de cela ne sont que des spéculations d'observation, mais je peux transmettre cela comme un bogue, à moins que quelqu'un puisse offrir une analyse plus complète.

Mise à jour (pour clôture, TOC, documentation, etc.)

Comme l'indiquent les commentaires, la version de Xamarin.Forms que j'utilisais (4.2.0) avait un bogue qui a été corrigé dans les versions ultérieures.

Articles connexes


Comment changer de page dans Xamarin.Forms?

Eric: Comment basculer entre les pages dans Xamarin Forms? Ma page principale est une ContentPage et je ne veux pas passer à quelque chose comme une page à onglets. J'ai pu le pseudo-faire en trouvant les parents des contrôles qui devraient déclencher la nouve

Coller la mise en page dans Xamarin Forms en bas

Huub S: Je crée une application dans des formulaires Xamarin mais j'ai du mal à coller une disposition au bas de l'appareil. Je pensais qu'un AbsoluteLayout fonctionnerait, mais je ne peux pas comprendre comment cela fonctionne. J'ai donc créé un RelativeLayou

Changer de page après la connexion dans Xamarin Forms

Ahmed Shamel J'ai une application de formulaire xamarin qui a une page de connexion. Lorsque l'utilisateur se connecte avec succès, l'application accède à MainPageMenuune page principale de détails. J'ai le même problème. Voici mon code dans app.cs: public App

Que se passe-t-il dans OnAppearing of Xamarin Forms?

Alan2 J'ai une application Forms qui fonctionne bien mais je remarque que les couleurs d'arrière-plan apparaissent incorrectement pendant une fraction de seconde lorsque la page apparaît. J'ai ce code pour mon OnAppearing protected override async void OnAp

Alternative à base.OnAppearing dans Xamarin.Forms

stephen.webb Questions de base, existe-t-il une alternative à base.OnAppearing qui ne fonctionnera qu'une seule fois? Actuellement, dans OnAppearing, j'ai un script qui génère des cadres en fonction du résultat d'une requête. Si je verrouille l'écran et que je

Événement Page.Loaded approprié dans Xamarin.Forms

Abdel Fattah Radwan Au cours des 2 derniers mois, j'ai cherché sans relâche un moyen d'implémenter un Page.Loadedévénement approprié lors de l'utilisation de Xamarin.Forms, mais je n'ai pas pu implémenter ou trouver un moyen de le faire. La plupart des gens su

Xamarin Forms - Variable d'accès dans une autre page

Barney Chambers J'ai une fonction dans ma MainPage.xaml.cs, et quand elle est appelée, je voudrais changer le texte sur une étiquette dans une autre page appelée Dashboard.xaml.cs Comment modifier des variables et appeler des fonctions entre des fichiers dans

Page de détail principale dans xamarin.forms

sahithi Je voudrais savoir s'il est possible d'afficher toujours la page maître, cela signifie que même après avoir cliqué sur quelque chose dans la page maître, il doit naviguer vers une autre page, mais la page maître doit toujours être visible. Will Decker