Bienvenue à Blogs CodeS-SourceS Identification | Inscription | Aide

Abonnements

Actualités

Shift

View Georges Legros' profile on LinkedIn


[Silverlight] Behaviors et Triggers

Introduction

Comme promis dans un précédent article, je reviens pour vous parler des Behaviors et des triggers de Silverlight 3.

Ceux qui connaissent WPF le confirmeront, les Triggers sont à la fois extrêmement pratique et puissant. C’est d’ailleurs l’une des choses qu’un développeur WPF regrette le plus lorsqu’il commence à développer en Silverlight.

La troisième mouture de Silverlight arrive donc à point nommé.image

Ou se cachent-ils ?

Arrêtez tout de suite de chercher dans les librairies par défaut de Silverlight, vous ne trouverez rien…

En effet, ces librairies ne font pas partie du Framework mais proviennent du SDK de … Microsoft Expression Blend 3.

Vous trouverez donc les DLL voulue à cet endroit :
C:\Program Files\Microsoft SDKs\Expression\Blend 3\Interactivity\Libraries\Silverlight
[Si vous avez un OS 64, il se peut que ce soit dans « Program Files (x86) » ]

Si vous n’avez pas de licence pour Blend, pas de panique… vous pouvez télécharger une version d’évaluation ici (http://expression.microsoft.com/en-us/cc136523.aspx).

De quoi ai-je besoin ?

Je vais ici parler principalement de 3 classes à savoir Behavior, TriggerAction and TargetedTriggerAction.

Behaviorimage

Pour les allergiques à l’anglais, ce mot signifie « comportement ». En d’autres termes, il s’agit de définir ce qu’un composant va faire lorsqu’il sera face à une situation particulière…

On aura accès à l’élément associé grâce à la propriété AssociatedObject de type T.

public class FillBehavior : Behavior<Shape>
{
private List<Color> colors = new List<Color> { Colors.Red, Colors.Magenta, Colors.Cyan, Colors.Green, Colors.Purple };
private int index;
protected override void OnAttached()
{
base.OnAttached();
 
AssociatedObject.MouseLeftButtonUp += AssociatedObject_MouseLeftButtonUp;
}
 
protected override void OnDetaching()
{
base.OnDetaching();
 
AssociatedObject.MouseLeftButtonUp -= AssociatedObject_MouseLeftButtonUp;
}
 
private void AssociatedObject_MouseLeftButtonUp(object sender, MouseButtonEventArgs e)
{
index++;
if (index >= colors.Count)
index = 0;
AssociatedObject.Fill = new SolidColorBrush(colors[index]);
}
}
 

Comme on peut le voir ici, nous surchargeons simplement la méthode OnAttached et OnDetaching. C’est Le Behavior qui se lie à l’évènement MouseLeftButtonDown, le contrôle auquel on attachera le behavior n’aura donc rien à faire.

Voici comment lier le Behavior à un élément en XAML :

<Rectangle x:Name="shape">
<Interactivity:Interaction.Behaviors>
<Behaviors:FillBehavior />
</Interactivity:Interaction.Behaviors>
      </Rectangle>
 

Ou en C# :

FillBehavior behavior = new FillBehavior();
behavior.Attach(shape);

 

TriggerAction<T> image

Ici on va gagner en flexibilité… La classe que nous écrirons ne sera plus responsable dans le choix de l’évènement auquel réagir.

L’utilisateur pourra donc décider de quand exécuter l’action.

Nous aurons toujours accès à l’AssociatedObject mais également  à l’eventArgs correspondant à l’évènement utilisé.

Ici l’action ne sera pas exécutée dans un Event Handler mais dans la méthode Invoke qu’il faudra évidemment surcharger :

protected override void Invoke(object parameter)
{
index++;
if (index >= colors.Count)
index = 0;
AssociatedObject.Fill = new SolidColorBrush(colors[index]);
}
 

Si le principe est similaire, il faut ici voir une sorte d’event handler réutilisable et que l’on peut attacher à des évènements de natures différentes.

En ce qui concerne la méthode utilisée pour attacher le Trigger, c’est similaire à celle utilisée pour le Behavior:

<Rectangle x:Name="shape">
<Interactivity:Interaction.Triggers>
<Interactivity:EventTrigger EventName="MouseLeftButtonUp">
<TriggerAction:FillTriggerAction/>
</Interactivity:EventTrigger>
</Interactivity:Interaction.Triggers>
</Rectangle>

TargetedTriggerAction<T> image

Ici on prend les même et on recommence… ou presque.

Il s’agit cette fois de s’attacher à un event provenant d’un contrôle mais à exécuter l’action sur un autre.

On pourra donc récupérer le click (par exemple) sur un bouton et exécuter une action sur un Rectangle à un autre endroit.

Concernant le code, il n’y a pas de différence majeure à noter sauf que cette fois-ci on n’effectue une action sur la cible, Target.

protected override void Invoke(object parameter)
{
index++;
if (index >= colors.Count)
index = 0;
Target.Fill = new SolidColorBrush(colors[index]);
}
 

Attacher le trigger sera également un peu différent puisqu’on devra le faire à partir de la source et non de la cible:

<Button Content="Click here !!">
<Interactivity:Interaction.Triggers>
<Interactivity:EventTrigger EventName="Click">
<TargetedTriggerAction:FillTargetedTriggerAction TargetName="shape"/>
</Interactivity:EventTrigger>
</Interactivity:Interaction.Triggers>
</Button>

Pour aller plus loin…

… vous pouvez aussi utiliser les 2 attributs suivants:

DefaultTrigger

Utilisé sur un TriggerAction<T>, celui-ci vous permet de spécifier en fonction de l’AssociatedObject, l’évènement par défaut utilisé.

Attention à ne pas se méprendre, cela ne permet pas au développeur de rajouter le trigger sans spécifier l’évènement.

Cette information sera utilisée pas Blend lorsque vous utiliserez le trigger depuis l’éditeur.

[DefaultTrigger(typeof(Rectangle), typeof(EventTrigger), "MouseLeftButtonUp")]

Notez aussi que vous pouvez en utiliser plusieurs sur un seul trigger. Vous pourrez alors définir des event par défaut différent pour un Button et pour un Rectangle.

TypeConstraint

Dans le cas d’un TargetedTrigger<T>, le T est le type de l’objet Target. Le type de l’objet cible lui n’est pas défini.

Si vous souhaitez le définir, vous devez le faire via le TypeConstraint comme ceci :

[TypeConstraint(typeof(Button))]

Attention, si le type utilisé dans le Xaml n’est pas celui de la contrainte, il n’y aura pas d’erreur de Build. Vous aurez par contre un plantage au runtime.

En conclusion,

Voici donc 3 classes vraiment très pratique que je ne peux que vous recommander.

Je vous conseille également de regarder dans Microsoft Expression Blend 3 avant de créer votre propre Trigger ou Behavior car il en existe déjà quelques uns très pratique.

 

A très bientôt,

 

DjoDjo

Ce post vous a plu ? Ajoutez le dans vos favoris pour ne pas perdre de temps à le retrouver le jour où vous en aurez besoin :

Publié dimanche 15 novembre 2009 13:43 par DjoDjo

Classé sous :

Commentaires

Pas de commentaires

Les commentaires anonymes sont désactivés

Les 10 derniers blogs postés

- Conf’SharePoint : 10 bonnes raisons pour ne pas la rater par Le petit blog de Pierre / Pierre's little blog le 05-14-2013, 02:24

- [Event] Soirée de lancement Agile .NET France à Lyon par Blog Agile/ALM de Vincent THAVONEKHAM le 05-13-2013, 01:29

- .NET / Debug : inspection de la mémoire d'applications .NET (dump ou processus live) : première livraison d'une librairie .NET par Microsoft par CoqBlog le 05-11-2013, 22:21

- SharePoint : Incompatibilité avec Internet Explorer 10 (IE10) par Blog Technique de Romelard Fabrice le 05-08-2013, 16:29

- AutoSPInstaller pour SharePoint 2013 maintenant disponible en “RTM” par Julien Chable le 05-06-2013, 23:30

- [TFS2010] A la recherche du Shelveset perdu par Blog de Jérémy Jeanson le 05-03-2013, 21:46

- .NET / Debug post-mortem : obtenir le fichier mscordacwks.dll correspondant à un dump quand on n'a plus d'accès direct à ce fichier par CoqBlog le 04-28-2013, 19:57

- [W8] Afficher un graphe par CPU dans le gestionnaire des tâches par Blog de Jérémy Jeanson le 04-28-2013, 17:48

- [WCF] Limiter proprement l’accès à vos ressources serveur par Blog de Jérémy Jeanson le 04-26-2013, 22:59

- Event : Je serai speaker à la Conf’SharePoint par Blog Technique de Romelard Fabrice le 04-26-2013, 12:00