web-dev-qa-db-fra.com

Désactiver ToolbarItem Xamarin.Forms

J'ai le suivant sur ma page:

<ContentPage.ToolbarItems>
    <ToolbarItem Text="Run" Command="{Binding RunCommand}" />
</ContentPage.ToolbarItems>

La commande démarre une tâche async ..... J'essaie de désactiver le contrôle tant que la tâche async est toujours en cours d'exécution en le liant à une propriété booléenne comme suit:

<ContentPage.ToolbarItems>
    <ToolbarItem Text="Run" Command="{Binding RunCommand}" IsEnabled="{Binding MyBoolProperty}" />
</ContentPage.ToolbarItems>

Mon problème est qu'il ne semble pas exister de propriété "IsEnabled" pour ToolbarItem. Existe-t-il un moyen de réaliser ce que j'essaye de faire avec Xamarin.Forms?

17
LostBalloon

Après l’aide du support technique de William et Xamarin, j’ai enfin pu comprendre comment fonctionne la fonctionnalité.

C’est un peu contre-intuitif car nous nous attendons à activer/désactiver le bouton (ToolbarItem), mais nous devons en réalité gérer l’état de la commande liée au bouton. Une fois que nous comprenons ce modèle, cela a du sens.

L'objet Command de type ICommand a une propriété CanExecute (merci à William de l'avoir signalé) Désormais, vous ne voulez pas y accéder directement, à moins que ce ne soit pour vérifier si la commande peut être exécutée ou non.

Où que vous souhaitiez dans votre code, pour modifier l'état de la commande, vous devez ajouter la ligne suivante:

((Command)_myCommand).ChangeCanExecute();

Cette ligne forcera la propriété CanExecute à être réévaluée pour la commande spécifiée.

J'ai personnellement décidé de l'ajouter là où je surveille l'inactivité telle qu'elle était logique dans ma candidature.

public bool Inactive { 
    get { 
        return _inactive;
    } 
    set {
        if (_inactive != value) {
            _inactive = value;
            ((Command)_myCommand).ChangeCanExecute();
            OnPropertyChanged ();
        }
    }
}

Dans la vue, il n'y a aucun changement à noter:

<ToolbarItem Text="Run" Command="{Binding MyCommand}" />

Désormais, lorsque vous créez l’objet Command, c’est là que le gros travail sera effectué. Nous utilisons généralement le constructeur à un seul argument, car il suffit généralement et c’est là que nous définissons ce que fait notre commande. Il est intéressant de noter qu’il existe également un constructeur à 2 paramètres dans lequel vous pouvez fournir la fonction/action qui détermine la valeur de la propriété CanExecute.

_myCommand = new Command (async () => {
                                          Inactive = false;
                                          await Run();
                                          Inactive = true;
                                      },
                                      () => {
                                          return Inactive;
                                      });


public ICommand MyCommand {
    get { 
        return _myCommand;
    }
}

Edit: Je sais que vous devez modifier techniquement la valeur de Inactive dans Run (), mais à des fins de démonstration ...

17
LostBalloon

Ce que j'ai appris à faire dans ces situations est le suivant:

public Command RunCommand 
{ 
    get { return new Command(async() => await OnRunCommand()); }
}    

private bool _isRunning;

public async Task OnRunCommand() 
{
    if (_isRunning) return;
    _isRunning = true;

    // do stuff

    _isRunning = false;
}

Le inconvénient: cela laisse l'élément de la barre d'outils dans son état normal et les utilisateurs peuvent continuer à l'exploiter.

Le upside: cela n'autorisera pas les tâches simultanées OnRunCommand, ce qui est bien.

Si vous souhaitez poursuivre la désactivation du bouton en affichant une image désactivée, vous devez créer un moteur de rendu.

Si vous ne souhaitez pas afficher l'élément de la barre d'outils pendant que la tâche est en cours d'exécution, envisagez de supprimer l'élément de la barre d'outils de la page et de l'ajouter ultérieurement.

1
Will Decker

Cet exemple consiste à supprimer, non pas désactiver mais peut aussi être pratique.

    ToolbarItem delToolbar;       

    ...

        delToolbar = new ToolbarItem
        {
            Order = ToolbarItemOrder.Primary,                
            Text = "delete",              
            Command = new Command(async () =>
            {                                       
                ToolbarItems.Remove(delToolbar);
            })
        };
        ToolbarItems.Add(delToolbar);
1
Kaptein Babbalas