Métadonnées de propriété de dépendance

Le système de propriétés Windows Presentation Foundation (WPF) inclut un système de création de rapports de métadonnées qui va au-delà de ce qui peut être signalé à propos d’une propriété par le biais de caractéristiques clR (Common Language Runtime) générales ou de réflexion. Les métadonnées d’une propriété de dépendance peuvent également être affectées de manière unique par la classe qui définit une propriété de dépendance, peuvent être changées quand la propriété de dépendance est ajoutée à une autre classe, et peuvent être substituées de manière spécifique par toutes les classes dérivées qui héritent de la propriété de dépendance de la classe de base de définition.

Prérequis

Cette rubrique suppose que vous comprenez les propriétés de dépendance du point de vue d’un consommateur de propriétés de dépendance existantes sur les classes WPF et que vous avez lu la vue d’ensemble des propriétés de dépendance. Pour pouvoir suivre les exemples de cette rubrique, vous devez également comprendre le langage XAML et savoir comment écrire des applications WPF.

Utilisation des métadonnées de propriété de dépendance

Les métadonnées de propriété de dépendance existent en tant qu’objet qui peut être interrogé pour examiner les caractéristiques d’une propriété de dépendance. Ces métadonnées sont également souvent sollicitées par le système de propriétés quand il traite des propriétés de dépendance. L’objet de métadonnées pour une propriété de dépendance peut contenir les types d’informations suivants :

  • Valeur par défaut de la propriété de dépendance, si aucune autre valeur ne peut être déterminée pour la propriété de dépendance par valeur locale, style, héritage, etc. Pour une discussion approfondie sur la façon dont les valeurs par défaut participent à la priorité utilisée par le système de propriétés lors de l’attribution de valeurs pour les propriétés de dépendance, consultez Priorité de la valeur de propriété de dépendance.

  • Références aux implémentations de rappels qui affectent les comportements de forçage ou de notification de modification en fonction du type de propriétaire. Notez que ces rappels sont souvent définis avec un niveau d’accès non public. Ainsi, il n’est généralement pas possible d’obtenir les références réelles à partir des métadonnées, sauf si les références sont dans votre étendue d’accès autorisée. Pour plus d’informations sur les rappels de propriété de dépendance, consultez Validation et rappels de propriétés de dépendance.

  • Si la propriété de dépendance en question est considérée comme une propriété de niveau framework WPF, les métadonnées peuvent contenir des caractéristiques de propriété de dépendance de niveau framework WPF qui fournissent des informations et indiquent l’état de services tels que le moteur de disposition de niveau framework WPF et la logique d’héritage de propriété. Pour plus d’informations sur cet aspect des métadonnées de propriété de dépendance, consultez Métadonnées de propriété de framework.

API de métadonnées

Le type qui signale la plupart des informations de métadonnées utilisées par le système de propriétés est la PropertyMetadata classe. Des instances de métadonnées sont éventuellement spécifiées quand les propriétés de dépendance sont inscrites auprès du système de propriétés, et peuvent également être spécifiées pour d’autres types qui s’ajoutent comme propriétaires ou remplacent les métadonnées dont ils héritent à partir de la définition de propriété de dépendance de la classe de base. (Dans les cas où une inscription de propriété ne spécifie pas de métadonnées, une valeur par défaut PropertyMetadata est créée avec des valeurs par défaut pour cette classe.) Les métadonnées inscrites sont retournées comme PropertyMetadata lorsque vous appelez les différentes GetMetadata surcharges qui obtiennent des métadonnées à partir d’une propriété de dépendance sur une DependencyObject instance.

La PropertyMetadata classe est ensuite dérivée de pour fournir des métadonnées plus spécifiques pour les divisions architecturales telles que les classes au niveau du framework WPF. UIPropertyMetadata ajoute des rapports d’animation et FrameworkPropertyMetadata fournit les propriétés au niveau de l’infrastructure WPF mentionnées dans la section précédente. Lorsque les propriétés de dépendance sont inscrites, elles peuvent être inscrites auprès de ces PropertyMetadata classes dérivées. Lorsque les métadonnées sont examinées, le type de base PropertyMetadata peut potentiellement être converti en classes dérivées afin de pouvoir examiner les propriétés plus spécifiques.

Remarque

Les caractéristiques de propriété qui peuvent être spécifiées sont FrameworkPropertyMetadata parfois appelées « indicateurs » dans cette documentation. Lorsque vous créez de nouvelles instances de métadonnées à utiliser dans les inscriptions de propriétés de dépendance ou les substitutions de métadonnées, vous spécifiez ces valeurs à l’aide de l’énumération FrameworkPropertyMetadataOptions au niveau de l’indicateur, puis vous fournissez éventuellement des valeurs concaténées de l’énumération au FrameworkPropertyMetadata constructeur. Toutefois, une fois construites, ces caractéristiques d’option sont exposées dans une FrameworkPropertyMetadata série de propriétés booléennes plutôt que dans la valeur d’énumération de construction. Les propriétés booléennes vous permettent de vérifier chaque condition, plutôt que d’avoir à appliquer un masque à une valeur d’énumération d’indicateurs pour obtenir les informations qui vous intéressent. Le constructeur utilise le concaténé FrameworkPropertyMetadataOptions afin de conserver la longueur de la signature du constructeur raisonnable, tandis que les métadonnées construites réelles exposent les propriétés discrètes pour rendre l’interrogation des métadonnées plus intuitives.

Quand substituer des métadonnées, quand dériver une classe ?

Le système de propriétés WPF a établi des fonctionnalités permettant de modifier certaines caractéristiques des propriétés de dépendance sans les obliger à être entièrement réinscrites. Pour cela, vous devez construire une instance différente des métadonnées de propriété pour la propriété de dépendance telle qu’elle existe sur un type particulier. Notez que la plupart des propriétés de dépendance existantes ne sont pas des propriétés virtuelles. Ainsi, à proprement parler, vous ne pouvez les « réimplémenter » sur des classes héritées qu’en occultant le membre existant.

Si le scénario que vous tentez d’activer pour une propriété de dépendance sur un type ne peut pas être obtenu en changeant les caractéristiques des propriétés de dépendance existantes, il peut être nécessaire de créer une classe dérivée, puis de déclarer une propriété de dépendance personnalisée sur votre classe dérivée. Une propriété de dépendance personnalisée se comporte de façon identique aux propriétés de dépendance définies par les API WPF. Pour plus d’informations sur les propriétés de dépendance personnalisées, consultez Propriétés de dépendance personnalisées.

L’une des caractéristiques principales d’une propriété de dépendance que vous ne pouvez pas substituer est son type de valeur. Si vous héritez d’une propriété de dépendance qui a le comportement approximatif souhaité, mais que vous avez besoin pour elle d’un type différent, vous devrez implémenter une propriété de dépendance personnalisée et peut-être lier les propriétés par l’intermédiaire de la conversion de type ou autre implémentation sur votre classe personnalisée. En outre, vous ne pouvez pas remplacer un rappel existant ValidateValueCallback, car ce rappel existe dans le champ d’inscription lui-même et non dans ses métadonnées.

Scénarios de changement des métadonnées existantes

Si vous travaillez avec des métadonnées d’une propriété de dépendance existante, un scénario courant de changement des métadonnées de propriété de dépendance consiste à modifier la valeur par défaut. Le changement ou l’ajout de rappels du système de propriétés est un scénario plus avancé. Vous souhaiterez peut-être le faire si votre implémentation d’une classe dérivée a des corrélations différentes entre des propriétés de dépendance. L’une des conditions pour disposer d’un modèle de programmation qui prend en charge à la fois le code et l’utilisation déclarative est que les propriétés doivent pouvoir être définies dans n’importe quel ordre. Par conséquent, toutes les propriétés dépendantes doivent être définies juste-à-temps sans contexte et ne peuvent pas reposer sur la connaissance d’un ordre de définition tel que celui que l’on pourrait trouver dans un constructeur. Pour plus d’informations sur cet aspect du système de propriétés, consultez Validation et rappels de propriétés de dépendance. Notez que les rappels de validation ne font pas partie des métadonnées ; ils font partie de l’identificateur de propriété de dépendance. Ainsi, vous ne pouvez pas changer les rappels de validation en substituant les métadonnées.

Dans certains cas, vous souhaiterez peut-être modifier les options de métadonnées de propriété de niveau framework WPF sur des propriétés de dépendance existantes. Ces options communiquent certaines conditions connues sur les propriétés de niveau framework WPF à d’autres processus de niveau framework WPF tels que le système de disposition. La définition des options est généralement effectuée uniquement lors de l’inscription d’une nouvelle propriété de dépendance, mais il est également possible de modifier les métadonnées de propriété au niveau de l’infrastructure WPF dans le cadre d’un appel ou AddOwner d’un OverrideMetadata appel. Pour connaître les valeurs spécifiques à utiliser et pour plus d’informations, consultez Métadonnées de propriété de framework. Pour plus d’informations sur la façon dont ces options doivent être définies pour une propriété de dépendance récemment inscrite, consultez Propriétés de dépendance personnalisées.

Substitution de métadonnées

La substitution de métadonnées a pour objectif principal de vous permettre de changer les différents comportements dérivés des métadonnées qui sont appliqués à la propriété de dépendance telle qu’elle existe sur votre type. Les raisons sont expliquées plus en détail dans la section Métadonnées. Pour plus d’informations et pour obtenir des exemples de code, consultez Substituer les métadonnées d’une propriété de dépendance.

Les métadonnées de propriété peuvent être fournies pour une propriété de dépendance pendant l’appel d’inscription (Register). Toutefois, dans de nombreux cas, vous souhaiterez peut-être fournir des métadonnées propres au type pour votre classe quand elle hérite de cette propriété de dépendance. Pour ce faire, appelez la OverrideMetadata méthode. Pour obtenir un exemple à partir des API WPF, la FrameworkElement classe est le type qui inscrit d’abord la Focusable propriété de dépendance. Toutefois, la Control classe remplace les métadonnées de la propriété de dépendance pour fournir sa propre valeur par défaut initiale, en la remplaçant par falsetrue, et utilise à nouveau l’implémentation d’origine Focusable .

Quand vous substituez des métadonnées, les différentes caractéristiques des métadonnées sont fusionnées ou remplacées.

  • PropertyChangedCallback est fusionné. Si vous ajoutez un nouveau PropertyChangedCallbackrappel, ce rappel est stocké dans les métadonnées. Si vous ne spécifiez pas d’élément PropertyChangedCallback dans le remplacement, la valeur de PropertyChangedCallback celle-ci est promue en tant que référence à partir de l’ancêtre le plus proche qui l’a spécifiée dans les métadonnées.

  • Le comportement PropertyChangedCallback réel du système de propriétés est que les implémentations pour tous les propriétaires de métadonnées de la hiérarchie sont conservées et ajoutées à une table, avec l’ordre d’exécution par le système de propriétés étant que les rappels de la classe la plus dérivée sont appelés en premier.

  • DefaultValue est remplacé. Si vous ne spécifiez pas d’élément DefaultValue dans le remplacement, la valeur de DefaultValue provient de l’ancêtre le plus proche qui l’a spécifiée dans les métadonnées.

  • CoerceValueCallback les implémentations sont remplacées. Si vous ajoutez un nouveau CoerceValueCallbackrappel, ce rappel est stocké dans les métadonnées. Si vous ne spécifiez pas d’élément CoerceValueCallback dans le remplacement, la valeur de CoerceValueCallback celle-ci est promue en tant que référence à partir de l’ancêtre le plus proche qui l’a spécifiée dans les métadonnées.

  • Le comportement du système de propriétés est que seules les CoerceValueCallback métadonnées immédiates sont appelées. Aucune référence à d’autres CoerceValueCallback implémentations de la hiérarchie n’est conservée.

Ce comportement est implémenté par Merge, et peut être substitué sur les classes de métadonnées dérivées.

Substitution de métadonnées de propriété jointe

Dans WPF, les propriétés jointes sont implémentées en tant que propriétés de dépendance. Cela signifie qu’elles ont également des métadonnées de propriété, que les différentes classes peuvent substituer. Les considérations exploratoires relatives à une propriété jointe dans WPF sont généralement que toutes les DependencyObject propriétés associées peuvent être définies sur elles. Par conséquent, toute DependencyObject classe dérivée peut remplacer les métadonnées d’une propriété jointe, car elle peut être définie sur une instance de la classe. Vous pouvez substituer les valeurs par défaut, les rappels ou les propriétés de rapport de caractéristiques de niveau framework WPF. Si la propriété jointe est définie sur une instance de votre classe, ces caractéristiques de métadonnées de propriété de substitution s’appliquent. Par exemple, vous pouvez substituer la valeur par défaut de telle sorte que votre valeur de remplacement soit signalée comme valeur de la propriété jointe sur des instances de votre classe chaque fois que la propriété n’est pas définie autrement.

Remarque

La Inherits propriété n’est pas pertinente pour les propriétés jointes.

Ajout d’une classe en tant que propriétaire d’une propriété de dépendance existante

Une classe peut s’ajouter en tant que propriétaire d’une propriété de dépendance qui a déjà été inscrite, à l’aide de la AddOwner méthode. Cela permet à la classe d’utiliser une propriété de dépendance initialement inscrite pour un autre type. La classe d’ajout n’est généralement pas une classe dérivée du type ayant inscrit initialement cette propriété de dépendance comme propriétaire. En pratique, cela permet à votre classe et à ses classes dérivées d’« hériter » d’une implémentation de propriété de dépendance sans que la classe propriétaire d’origine et la classe d’ajout ne soient dans la même vraie hiérarchie de classes. En outre, la classe d’ajout (et aussi toutes les classes dérivées) peuvent ensuite fournir des métadonnées propres au type pour la propriété de dépendance d’origine.

En plus de s’ajouter comme propriétaire par l’intermédiaire des méthodes utilitaires du système de propriétés, la classe d’ajout doit déclarer des membres publics supplémentaires sur elle-même pour que la propriété de dépendance participe totalement au système de propriétés avec exposition à la fois au code et au balisage. Une classe qui ajoute une propriété de dépendance existante a les mêmes responsabilités, en ce qui concerne l’exposition du modèle objet pour cette propriété de dépendance, qu’une classe qui définit une nouvelle propriété de dépendance personnalisée. Le premier membre de ce genre à exposer est un champ identificateur de propriété de dépendance. Ce champ doit être un public static readonly champ de type DependencyProperty, qui est affecté à la valeur de retour de l’appel AddOwner . Le deuxième membre à définir est la propriété « wrapper » du Common Language Runtime (CLR). Le wrapper facilite considérablement la manipulation de votre propriété de dépendance dans le code (vous évitez les appels à SetValue chaque fois et ne pouvez effectuer cet appel qu’une seule fois dans le wrapper lui-même). Le wrapper est implémenté exactement comment il le serait si vous inscriviez une propriété de dépendance personnalisée. Pour plus d’informations sur l’implémentation d’une propriété de dépendance, consultez Propriétés de dépendance personnalisées et Ajouter un type propriétaire d’une propriété de dépendance.

AddOwner et les propriétés jointes

Vous pouvez appeler AddOwner une propriété de dépendance définie comme propriété jointe par la classe propriétaire. En général, ceci a pour but d’exposer la propriété précédemment jointe en tant que propriété de dépendance non jointe. Vous allez ensuite exposer la AddOwner valeur de retour en tant que public static readonly champ à utiliser comme identificateur de propriété de dépendance et définir les propriétés « wrapper » appropriées afin que la propriété apparaisse dans la table des membres et prenne en charge une utilisation des propriétés non jointes dans votre classe.

Voir aussi