Bienvenue à Blogs CodeS-SourceS Identification | Inscription | Aide

.NET 3.0 : Comprendre les dependency properties et les propriétés attachées

Avec WPF, le databinding entre des objets métiers et l'interface utilisateur est devenu très facile. Par exemple, il est possible de lier une ListBox avec une collection d'objets métiers, et WPF se charge d'afficher comme il faut cette collection.

Il est même possible que WPF mettre automatiquement à jour l'interface à chaque modification de votre objet source. Pour cela, il y a deux possibilités. La première solution est que votre objet implémente INotifyPropertyChanged, et déclenche l'évènement PropertyChanged à chaque fois qu'une propriété est modifiée. WPF est alors obligé d'utiliser la réflexion.

Les dependency properties

La solution que nous allons aborder ici est d'utiliser des dependency objects. Cette classe est la base d'une très grande partie des classes WPF, et elle est aussi utilisée dans WF. Les dependency objects permettent d'utiliser des dependency properties.

Les dependency properties permettent aux objets d'avoir des propriétés dont la valeur peut dépendre de nombreuses choses. Par exemple, du data binding avec une autre propriété, ou d'une animation. En plus, elles fournissent un support pour l'auto validation et les valeurs par défaut. Les classes dérivées peuvent modifier le comportement d'une dependency property héritée très simplement.

Déclarer une DependencyProperty

Cela se fait très simplement. La première chose nécessaire est que votre objet (ici Planet) dérive de DependencyObject. La seconde (et dernière) chose nécessaire est de déclarer la propriété au moteur de la façon suivante :

public static readonly DependencyProperty MassProperty = DependencyProperty.Register("Mass", typeof(float), typeof(Planet));

Cette ligne fait plusieurs choses. D'abord, elle indique au moteur de DependencyObject de .NET 3.0 que chaque objet de type Planet (3e paramètre) aura une propriété (au sens DependencyProperty) de type float (2e paramètre).

"Mass" (le 1er paramètre) représente le nom de la propriété tel qu'il pourra être utilisé en XAML, il n'y a donc pas besoin d'utiliser la réflexion.

Quant à la variable MassProperty, il s'agit d'une "clé" qui permet de référencer cette propriété depuis le code, lorsqu'on souhaite effectuer une opération sur cette propriété. Il existe souvent des alternatives permettant d'utiliser le string "Mass" à la place, mais l'utilisation de la variable MassProperty est plus efficace.

Les conventions de nommage préconisent que la clé ait la signature suivante :

public static readonly DependencyProperty [NomDeLaPropriété]Property;

Déclarer une propriété CLR encapsulant cette DependencyProperty

Pour que cette propriété soit utilisable depuis le code de façon totalement invisible (sans que l'on ait à se préoccuper qu'il s'agisse d'une DependencyProperty ou d'une propriété CLR), on définit une propriété CLR (bien sur, ce n'est pas du tout obligatoire).

public float Mass
{
    get { return (float
)GetValue(MassProperty); }
    set { SetValue(MassProperty, value
); }
}

GetValue est une méthode de DependencyObject qui renvoie la valeur de la propriété (au sens DependencyProperty) dont la clé est indiquée en paramètre (ici, MassProperty). Cette méthode renvoie un objet de type object. Il faut donc le reconvertir en float avant de le renvoyer. SetValue fonctionne de la même façon. Notez que si vous passez à SetValue un objet de type différent que celui que vous avez déclaré par l'appel à DependencyProperty.Register, le Framework lèvera une exception.

Le fait de déclarer cette propriété CLR permet donc de repasser à un typage fort, puisque la vérification des types n'est faite qu'à l'exécution avec les DependencyProperty.

Les conventions de nommage préconisent la signature suivante pour cette propriété CLR :

public [TypeDeLaPropriété] [NomDeLaPropriété] { get; set;}

Les propriétés attachées

Une propriété attachée est une DependencyProperty qui est attachée à n'importe quel DependencyObject et pas seulement au type qui la définit.

En fait le système des DependencyProperty est conçu pour qu'une propriété d'une instance n'occupe pas de mémoire tant que cette propriété n'a pas été modifiée. En effet, le moteur de DependencyProperty revoie, de manière transparente, la valeur par défaut (qu'il est possible de préciser lors de l'appel à DependencyProperty.Register) si la propriété n'a jamais été modifiée.

Les propriétés attachées utilisent ce principe. En effet, si on prend l'exemple de la propriété Dock d'un contrôle, elle n'est lue que lorsque ce contrôle est placé à l'intérieur d'un DockPanel. Cela peut arriver à n'importe quel type de contrôle. Pourtant le nombre d'instances qui modifieront cette propriété est statistiquement très faible dans une application. Donc placer un attribut dock dans tous les contrôles (comme c'était le cas pour les WinForms) conduit à un gâchis de mémoire. Les DependencyProperty évitent ce gâchis.

De plus, sans les propriétés attachées, il n'est pas possible de rajouter de propriété à la classe Control, car nous n'en sommes pas l'auteur.

Déclarer une DependencyProperty attachée

La déclaration d'une propriété attachée se fait de façon très semblable à une DependencyProperty classique :

public static readonly DependencyProperty TopProperty = DependencyProperty.RegisterAttached("Top", typeof(double), typeof(Canvas));

Les arguments sont les même que pour une DependencyProperty classique : Nom de la propriété, type de la propriété, type qui déclare cette propriété.

Les conventions de nommage sont également les mêmes pour la déclaration de la clé :

public static readonly DependencyProperty [NomDeLaPropriété]Property;

Déclarer des accesseurs CLR encapsulant cette propriété attachée

Cette fois ci, il n'est pas possible d'utiliser une propriété CLR car il doit être possible de modifier la valeur de la propriété pour n'importe quel autre type (dérivant de DependencyProperty), et pas seulement pour celui qui définit la propriété (ici Canvas).

On utilise donc deux méthodes statiques :

public static double GetTop(DependencyObject target)
{
    return (double
)target.GetValue(TopProperty);
}

public static void SetTop(DependencyObject target, double
value)
{
    target.SetValue(TopProperty, value);
}

Les guidelines préconisent d'utiliser les signatures suivantes pour ces deux méthodes :

public static [TypeDeLaPropriété] Get[NomDeLaPropriété](DependencyObject target);
public static void Set[NomDeLaPropriété](DependencyObject target, [TypeDeLaPropriété] value);

Conclusion

Le Framework .NET 3.0 est basé sur les DependencyProperty. WPF et WF les utilisent abondamment (WCF ne les utilise pas à ma connaissance). Elles fournissent les fonctionnalités suivantes :

  • Ressources
  • Data binding
  • Styles
  • Animations
  • Metadatas
  • Héritage

L'inconvénient principal, c'est qu'elles obligent l'objet qui les utilise à hériter de DependencyObject.

Pour plus d'informations, je vous conseille d'aller voir les pages suivantes :

Publié lundi 19 février 2007 15:53 par RaptorXP
Classé sous : , , , , ,
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 :

Commentaires

# re: .NET 3.0 : Comprendre les dependency properties et les propriétés attachées

Hello,

Merci pour ce très bon article! Par contre, le débutant que je suis à dut aller se renseigner pour avoir la def d'une attached property...

Merci encore !

+++

mardi 7 avril 2009 10:45 by jmix90
Les commentaires anonymes sont désactivés

Les 10 derniers blogs postés

- Merci par Blog de Jérémy Jeanson le 10-01-2019, 20:47

- Office 365: Script PowerShell pour auditer l’usage des Office Groups de votre tenant par Blog Technique de Romelard Fabrice le 04-26-2019, 11:02

- Office 365: Script PowerShell pour auditer l’usage de Microsoft Teams de votre tenant par Blog Technique de Romelard Fabrice le 04-26-2019, 10:39

- Office 365: Script PowerShell pour auditer l’usage de OneDrive for Business de votre tenant par Blog Technique de Romelard Fabrice le 04-25-2019, 15:13

- Office 365: Script PowerShell pour auditer l’usage de SharePoint Online de votre tenant par Blog Technique de Romelard Fabrice le 02-27-2019, 13:39

- Office 365: Script PowerShell pour auditer l’usage d’Exchange Online de votre tenant par Blog Technique de Romelard Fabrice le 02-25-2019, 15:07

- Office 365: Script PowerShell pour auditer le contenu de son Office 365 Stream Portal par Blog Technique de Romelard Fabrice le 02-21-2019, 17:56

- Office 365: Script PowerShell pour auditer le contenu de son Office 365 Video Portal par Blog Technique de Romelard Fabrice le 02-18-2019, 18:56

- Office 365: Script PowerShell pour extraire les Audit Log basés sur des filtres fournis par Blog Technique de Romelard Fabrice le 01-28-2019, 16:13

- SharePoint Online: Script PowerShell pour désactiver l’Option IRM des sites SPO non autorisés par Blog Technique de Romelard Fabrice le 12-14-2018, 13:01