Déclencheurs Xamarin.FormsXamarin.Forms Triggers

Télécharger l’exemple Télécharger l’exempleDownload Sample Download the sample

Les déclencheurs vous permettent d’exprimer des actions de manière déclarative en XAML. Les actions en question modifient l’apparence des contrôles en fonction des événements ou des modifications apportées aux propriétés.Triggers allow you to express actions declaratively in XAML that change the appearance of controls based on events or property changes.

Vous pouvez affecter directement un déclencheur à un contrôle, ou vous pouvez l’ajouter à un dictionnaire de ressources de niveau page ou de niveau application afin de l’appliquer à plusieurs contrôles.You can assign a trigger directly to a control, or add it to a page-level or app-level resource dictionary to be applied to multiple controls.

Il existe quatre types de déclencheurs :There are four types of trigger:

  • Déclencheur de propriétés : activé lorsqu’une propriété d’un contrôle est définie sur une valeur particulière.Property Trigger - occurs when a property on a control is set to a particular value.

  • Déclencheur de données : utilise la liaison de données pour son déclenchement, en se basant sur les propriétés d’un autre contrôle.Data Trigger - uses data binding to trigger based on the properties of another control.

  • Déclencheur d’événements : activé lorsqu’un événement se produit au niveau d’un contrôle.Event Trigger - occurs when an event occurs on the control.

  • Déclencheur multiple : permet de définir plusieurs conditions de déclenchement avant qu’une action ne se produise.Multi Trigger - allows multiple trigger conditions to be set before an action occurs.

Déclencheurs de propriétéProperty Triggers

Un déclencheur simple peut être exprimé entièrement en XAML, en ajoutant un élément Trigger à la collection de déclencheurs d’un contrôle.A simple trigger can be expressed purely in XAML, adding a Trigger element to a control's triggers collection. Cet exemple montre un déclencheur qui modifie la couleur d’arrière-plan d’un Entry lorsqu’il reçoit le focus :This example shows a trigger that changes an Entry background color when it receives focus:

<Entry Placeholder="enter name">
    <Entry.Triggers>
        <Trigger TargetType="Entry"
             Property="IsFocused" Value="True">
            <Setter Property="BackgroundColor" Value="Yellow" />
        </Trigger>
    </Entry.Triggers>
</Entry>

Les parties importantes de la déclaration d’un déclencheur sont :The important parts of the trigger's declaration are:

  • TargetType : type du contrôle auquel le déclencheur est appliqué.TargetType - the control type that the trigger applies to.

  • Property : propriété du contrôle qui est supervisé.Property - the property on the control that is monitored.

  • Value : valeur qui entraîne l’activation du déclencheur, pour la propriété supervisée.Value - the value, when it occurs for the monitored property, that causes the trigger to activate.

  • Setter : collection d’éléments Setter qui peuvent être ajoutés lorsque la condition de déclenchement est remplie.Setter - a collection of Setter elements can be added and when the trigger condition is met. Vous devez spécifier le Property et le Value à définir.You must specify the Property and Value to set.

  • EnterActions et ExitActions (non montrés ici) : sont écrits en code et peuvent être utilisés en plus des éléments Setter (ou à leur place).EnterActions and ExitActions (not shown) - are written in code and can be used in addition to (or instead of) Setter elements. Ils sont décrits ci-dessous.They are described below.

Application d’un déclencheur à l’aide d’un styleApplying a Trigger using a Style

Les déclencheurs peuvent également être ajoutés à une déclaration Style dans le ResourceDictionary d’un contrôle, d’une page ou d’une d’application.Triggers can also be added to a Style declaration on a control, in a page, or an application ResourceDictionary. Cet exemple déclare un style implicite (c’est-à-dire qu’aucun Key n’est défini), ce qui signifie qu’il s’applique à tous les contrôles Entryde la page.This example declares an implicit style (ie. no Key is set) which means it will apply to all Entry controls on the page.

<ContentPage.Resources>
    <ResourceDictionary>
        <Style TargetType="Entry">
                        <Style.Triggers>
                <Trigger TargetType="Entry"
                         Property="IsFocused" Value="True">
                    <Setter Property="BackgroundColor" Value="Yellow" />
                </Trigger>
            </Style.Triggers>
        </Style>
    </ResourceDictionary>
</ContentPage.Resources>

Déclencheurs de donnéesData Triggers

Les déclencheurs de données utilisent la liaison de données pour superviser un autre contrôle afin de provoquer l’appel de Setter.Data triggers use data binding to monitor another control to cause the Setters to get called. Au lieu de l’attribut Property d’un déclencheur de propriété, définissez l’attribut Binding de manière à surveiller la valeur spécifiée.Instead of the Property attribute in a property trigger, set the Binding attribute to monitor for the specified value.

L’exemple ci-dessous utilise la syntaxe de liaison de données {Binding Source={x:Reference entry}, Path=Text.Length}The example below uses the data binding syntax {Binding Source={x:Reference entry}, Path=Text.Length} qui est celle utilisée pour référencer les propriétés d’un autre contrôle.which is how we refer to another control's properties. Lorsque la longueur de entry est égale à zéro, le déclencheur est activé.When the length of the entry is zero, the trigger is activated. Dans cet exemple, le déclencheur désactive le bouton lorsque l’entrée est vide.In this sample the trigger disables the button when the input is empty.

<!-- the x:Name is referenced below in DataTrigger-->
<!-- tip: make sure to set the Text="" (or some other default) -->
<Entry x:Name="entry"
       Text=""
       Placeholder="required field" />

<Button x:Name="button" Text="Save"
        FontSize="Large"
        HorizontalOptions="Center">
    <Button.Triggers>
        <DataTrigger TargetType="Button"
                     Binding="{Binding Source={x:Reference entry},
                                       Path=Text.Length}"
                     Value="0">
            <Setter Property="IsEnabled" Value="False" />
        </DataTrigger>
    </Button.Triggers>
</Button>

Conseil : Lorsque vous évaluez Path=Text.Length, fournissez toujours une valeur par défaut pour la propriété cible (par exemple,Tip: when evaluating Path=Text.Length always provide a default value for the target property (eg. Text=""), car sinon, sa valeur sera null et le déclencheur ne fonctionnera pas comme prévu.Text="") because otherwise it will be null and the trigger won't work like you expect.

En plus de spécifier des Setter, vous pouvez également fournir EnterActions et ExitActions.In addition to specifying Setters you can also provide EnterActions and ExitActions.

Déclencheurs d’événementsEvent Triggers

L’ élément EventTrigger nécessite uniquement une propriété Event, comme "Clicked" dans l’exemple ci-dessous.The EventTrigger element requires only an Event property, such as "Clicked" in the example below.

<EventTrigger Event="Clicked">
    <local:NumericValidationTriggerAction />
</EventTrigger>

Notez qu’il n’y a aucun élément Setter, mais plutôt une référence à une classe définie par local:NumericValidationTriggerAction qui nécessite que xmlns:local soit déclaré dans le code XAML de la page :Notice that there are no Setter elements but rather a reference to a class defined by local:NumericValidationTriggerAction which requires the xmlns:local to be declared in the page's XAML:

<ContentPage xmlns="http://xamarin.com/schemas/2014/forms"
             xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
             xmlns:local="clr-namespace:WorkingWithTriggers;assembly=WorkingWithTriggers"

La classe implémente TriggerAction, ce qui signifie qu’elle doit fournir un remplacement pour la méthode Invoke qui est appelée chaque fois que l’événement déclencheur se produit.The class itself implements TriggerAction which means it should provide an override for the Invoke method that is called whenever the trigger event occurs.

Une implémentation d’action de déclencheur doit :A trigger action implementation should:

  • Implémenter la classe générique TriggerAction<T>, avec le paramètre générique correspondant au type de contrôle auquel le déclencheur doit être appliqué.Implement the generic TriggerAction<T> class, with the generic parameter corresponding with the type of control the trigger will be applied to. Vous pouvez utiliser des superclasses telles que VisualElement pour écrire des actions de déclencheur qui fonctionnent avec un large éventail de contrôles, ou vous pouvez spécifier un type de contrôle comme Entry.You can use superclasses such as VisualElement to write trigger actions that work with a variety of controls, or specify a control type like Entry.

  • Remplacer la méthode Invoke qui est appelée chaque fois que les critères de déclenchement sont remplis.Override the Invoke method - this is called whenever the trigger criteria are met.

  • Si vous le souhaitez, vous pouvez exposer des propriétés qui peuvent être définies dans le code XAML lorsque le déclencheur est déclaré (comme Anchor, Scale et Length dans cet exemple).Optionally expose properties that can be set in the XAML when the trigger is declared (such as Anchor, Scale, and Length in this example).

public class NumericValidationTriggerAction : TriggerAction<Entry>
{
    protected override void Invoke (Entry entry)
    {
        double result;
        bool isValid = Double.TryParse (entry.Text, out result);
        entry.TextColor = isValid ? Color.Default : Color.Red;
    }
}

Les propriétés exposées par l’action du déclencheur peuvent être définies dans la déclaration XAML de la façon suivante :The properties exposed by the trigger action can be set in the XAML declaration as follows:

<EventTrigger Event="TextChanged">
    <local:NumericValidationTriggerAction />
</EventTrigger>

Soyez prudent lorsque vous partagez des déclencheurs dans un ResourceDictionary. En effet, une même instance sera partagée entre plusieurs contrôles, donc tout état configuré une fois sera appliqué à tous les autres contrôles.Be careful when sharing triggers in a ResourceDictionary, one instance will be shared among controls so any state that is configured once will apply to them all.

Notez que les déclencheurs d’événements ne prennent pas en charge EnterActions et ExitActions qui sont décrits plus bas.Note that event triggers do not support EnterActions and ExitActions described below.

Déclencheurs multiplesMulti Triggers

Un MultiTrigger est similaire à un Trigger ou à un DataTrigger, à ceci près qu’il peut avoir plusieurs conditions.A MultiTrigger looks similar to a Trigger or DataTrigger except there can be more than one condition. Toutes les conditions doivent être remplies avant que les Setter ne soient déclenchés.All the conditions must be true before the Setters are triggered.

Voici un exemple de déclencheur pour un bouton qui lie deux entrées différentes (email et phone) :Here's an example of a trigger for a button that binds to two different inputs (email and phone):

<MultiTrigger TargetType="Button">
    <MultiTrigger.Conditions>
        <BindingCondition Binding="{Binding Source={x:Reference email},
                                   Path=Text.Length}"
                               Value="0" />
        <BindingCondition Binding="{Binding Source={x:Reference phone},
                                   Path=Text.Length}"
                               Value="0" />
    </MultiTrigger.Conditions>

  <Setter Property="IsEnabled" Value="False" />
    <!-- multiple Setter elements are allowed -->
</MultiTrigger>

La collection Conditions peut également contenir des éléments PropertyCondition comme ceci :The Conditions collection could also contain PropertyCondition elements like this:

<PropertyCondition Property="Text" Value="OK" />

Création d’un déclencheur multiple de type « tout exiger »Building a "require all" multi trigger

Le déclencheur multiple ne met à jour son contrôle que lorsque toutes les conditions sont remplies.The multi trigger only updates its control when all conditions are true. La condition « toutes les longueurs de champs sont égales à zéro » (par exemple, une page de connexion où toutes les entrées doivent être effectuées) est difficile à tester, car cela nécessite une condition où « Text.Length > 0 », ce qui ne peut pas être exprimé en XAML.Testing for "all field lengths are zero" (such as a login page where all inputs must be complete) is tricky because you want a condition "where Text.Length > 0" but this can't be expressed in XAML.

Pour cela, vous devez utiliser un IValueConverter.This can be done with an IValueConverter. Le code de convertisseur ci-dessous transforme la liaison Text.Length en un bool qui indique si un champ est vide ou non :The converter code below transforms the Text.Length binding into a bool that indicates whether a field is empty or not:

public class MultiTriggerConverter : IValueConverter
{
    public object Convert(object value, Type targetType,
        object parameter, CultureInfo culture)
    {
        if ((int)value > 0) // length > 0 ?
            return true;            // some data has been entered
        else
            return false;            // input is empty
    }

    public object ConvertBack(object value, Type targetType,
        object parameter, CultureInfo culture)
    {
        throw new NotSupportedException ();
    }
}

Pour utiliser ce convertisseur dans un déclencheur multiple, ajoutez-le d’abord au dictionnaire de ressources de la page (avec une définition d’espace de noms xmlns:local personnalisée) :To use this converter in a multi trigger, first add it to the page's resource dictionary (along with a custom xmlns:local namespace definition):

<ResourceDictionary>
   <local:MultiTriggerConverter x:Key="dataHasBeenEntered" />
</ResourceDictionary>

Le code XAML est fourni ci-dessous.The XAML is shown below. Notez les différences suivantes par rapport au premier exemple de déclencheur multiple :Note the following differences from the first multi trigger example:

  • Dans le bouton, IsEnabled="false" est défini par défaut.The button has IsEnabled="false" set by default.
  • Les conditions du déclencheur multiple utilisent le convertisseur pour transformer la valeur Text.Length en un boolean.The multi trigger conditions use the converter to turn the Text.Length value into a boolean.
  • Lorsque toutes les conditions sont true, la méthode setter définit la propriété IsEnabled du bouton sur true.When all the conditions are true, the setter makes the button's IsEnabled property true.
<Entry x:Name="user" Text="" Placeholder="user name" />

<Entry x:Name="pwd" Text="" Placeholder="password" />

<Button x:Name="loginButton" Text="Login"
        FontSize="Large"
        HorizontalOptions="Center"
        IsEnabled="false">
  <Button.Triggers>
    <MultiTrigger TargetType="Button">
      <MultiTrigger.Conditions>
        <BindingCondition Binding="{Binding Source={x:Reference user},
                              Path=Text.Length,
                              Converter={StaticResource dataHasBeenEntered}}"
                          Value="true" />
        <BindingCondition Binding="{Binding Source={x:Reference pwd},
                              Path=Text.Length,
                              Converter={StaticResource dataHasBeenEntered}}"
                          Value="true" />
      </MultiTrigger.Conditions>
      <Setter Property="IsEnabled" Value="True" />
    </MultiTrigger>
  </Button.Triggers>
</Button>

Ces captures d’écran montrent la différence entre les deux exemples de déclencheurs multiples.These screenshots show the difference between the two multi trigger examples above. Dans la partie supérieure des écrans, l’entrée de texte dans un seul Entry suffit à activer le bouton Save (Enregistrer).In the top part of the screens, text input in just one Entry is enough to enable the Save button. Dans la partie inférieure de l’écran, le bouton Login (Connexion) reste inactif jusqu’à ce que les deux champs contiennent des données.In the bottom part of the screens, the Login button remains inactive until both fields contain data.

EnterActions et ExitActionsEnterActions and ExitActions

Une autre façon d’implémenter des modifications lorsqu’un déclencheur est activé est d’ajouter des collections EnterActions et ExitActions, et de spécifier des implémentations TriggerAction<T>.Another way to implement changes when a trigger occurs is by adding EnterActions and ExitActions collections and specifying TriggerAction<T> implementations.

Vous pouvez fournir à la fois EnterActions et ExitActions ainsi que des Setter dans un déclencheur. Sachez toutefois que les Setter sont appelés immédiatement (ils n’attendent pas la fin de EnterAction ou de ExitAction).You can provide both EnterActions and ExitActions as well as Setters in a trigger, but be aware that the Setters are called immediately (they do not wait for the EnterAction or ExitAction to complete). Vous pouvez également tout effectuer dans le code sans utiliser de Setter.Alternatively you can perform everything in the code and not use Setters at all.

<Entry Placeholder="enter job title">
    <Entry.Triggers>
        <Trigger TargetType="Entry"
                 Property="Entry.IsFocused" Value="True">
            <Trigger.EnterActions>
                <local:FadeTriggerAction StartsFrom="0"" />
            </Trigger.EnterActions>

            <Trigger.ExitActions>
                <local:FadeTriggerAction StartsFrom="1" />
            </Trigger.ExitActions>
                        <!-- You can use both Enter/Exit and Setter together if required -->
        </Trigger>
    </Entry.Triggers>
</Entry>

Comme toujours, lorsqu’une classe est référencée dans du code XAML, vous devez déclarer un espace de noms tel que xmlns:local, comme indiqué ici :As always, when a class is referenced in XAML you should declare a namespace such as xmlns:local as shown here:

<ContentPage xmlns="http://xamarin.com/schemas/2014/forms"
             xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
             xmlns:local="clr-namespace:WorkingWithTriggers;assembly=WorkingWithTriggers"

Ce code FadeTriggerAction est fourni ci-dessous:The FadeTriggerAction code is shown below:

public class FadeTriggerAction : TriggerAction<VisualElement>
{
    public FadeTriggerAction() {}

    public int StartsFrom { set; get; }

    protected override void Invoke (VisualElement visual)
    {
            visual.Animate("", new Animation( (d)=>{
                var val = StartsFrom==1 ? d : 1-d;
                visual.BackgroundColor = Color.FromRgb(1, val, 1);

            }),
            length:1000, // milliseconds
            easing: Easing.Linear);
    }
}

Remarque : EnterActions et ExitActions sont ignorés par les déclencheurs d’événements.Note: EnterActions and ExitActions are ignored on Event Triggers.