Cette documentation est archivée et n’est pas conservée.

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

Mise à jour : novembre 2007

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

Cette rubrique comprend les sections suivantes.

Cette rubrique part du principe 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 Windows Presentation Foundation (WPF) et que vous avez lu Vue d'ensemble des propriétés de dépendance. Pour pouvoir suivre les exemples de cette rubrique, vous devez également maîtriser XAML et savoir écrire des applications WPF.

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. Le système de propriétés accède fréquemment à ces métadonnées lorsqu'il traite une propriété de dépendance donnée. L'objet de métadonnées d'une propriété de dépendance peut contenir les types suivants d'informations :

  • 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 la valeur locale, le style, l'héritage, etc. Pour une discussion complète de 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'assignation 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 rappel qui affectent des comportements de forçage ou de notification de modification selon le type de propriétaire. Notez que ces rappels sont souvent définis avec un niveau d'accès non public. Il n'est dès lors généralement pas possible d'obtenir les références réelles auprès des métadonnées à moins que les références se trouvent dans votre portée 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é d'infrastructure WPF, les métadonnées peuvent contenir des caractéristiques de propriété de dépendance d'infrastructure WPF, qui signalent les informations et l'état pour des services tels que le moteur de présentation et la logique d'héritage des propriétés d'infrastructure WPF. Pour plus d'informations sur cet aspect des métadonnées de propriété de dépendance, consultez Métadonnées de propriété d'infrastructure.

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

La classe PropertyMetadata est ensuite dérivée pour fournir des métadonnées plus spécifiques pour les divisions architecturales, telles que les classes d'infrastructure WPF. UIPropertyMetadata ajoute des rapports d'animation, et FrameworkPropertyMetadata fournit les propriétés d'infrastructure WPF mentionnées dans la section précédente. Lorsque les propriétés de dépendance sont enregistrées, elles peuvent être inscrites avec ces classes dérivées PropertyMetadata. Lorsque les métadonnées sont examinées, le type PropertyMetadata de base peut être casté aux classes dérivées afin que vous puissiez examiner les propriétés plus spécifiques.

Remarque :

Les caractéristiques de propriété qui peuvent être spécifiées dans FrameworkPropertyMetadata sont parfois appelées « indicateurs » dans cette documentation. Lorsque vous créez des instances de métadonnées à utiliser dans des inscriptions de propriété de dépendance ou des substitutions de métadonnées, vous spécifiez ces valeurs à l'aide de l'énumération d'indicateurs FrameworkPropertyMetadataOptions. Puis vous fournissez éventuellement les valeurs concaténées de l'énumération au constructeur de FrameworkPropertyMetadata. Cependant, une fois construites, ces caractéristiques d'option sont exposées dans des FrameworkPropertyMetadata comme série de propriétés booléennes et non comme valeur d'énumération constructive. Les propriétés booléennes vous permettent de vérifier chaque condition, au lieu de vous demander d'appliquer un masque à une valeur d'énumération d'indicateurs pour obtenir les informations qui vous intéressent. Le constructeur utilise les FrameworkPropertyMetadataOptions concaténées pour conserver une longueur de signature de constructeur raisonnable, alors que les métadonnées construites réelles exposent les propriétés discrètes pour rendre l'interrogation des métadonnées plus intuitive.

Le système de propriétés WPF dispose de fonctionnalités établies pour modifier certaines caractéristiques des propriétés de dépendance sans nécessiter leur réimplémentation totale. Pour cela, vous devez construire une autre instance des métadonnées de propriété pour la propriété de dépendance telle qu'elle existe dans un type particulier. Notez que la plupart des propriétés de dépendance existantes ne sont pas des propriétés virtuelles. Dès lors, pour les « réimplémenter » sur des classes héritées, vous devez occulter 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 accompli en modifiant les caractéristiques des propriétés de dépendance existantes, vous devrez peut-être créer une classe dérivée, puis 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 comme les propriétés de dépendance définies par les WPFAPI. Pour plus d'informations sur les propriétés de dépendance personnalisées, consultez Propriétés de dépendance personnalisées.

Vous ne pouvez pas substituer le type valeur d'une propriété de dépendance. Si vous héritez une propriété de dépendance qui a plus ou moins le comportement requis, mais que vous avez besoin d'un autre type, vous devrez implémenter une propriété de dépendance personnalisée et peut-être lier les propriétés par conversion de type ou autre implémentation sur votre classe personnalisée. De même, vous ne pouvez pas remplacer un ValidateValueCallback existant, parce que ce rappel existe dans le champ d'inscription lui-même et non dans ses métadonnées.

Si vous travaillez avec les métadonnées d'une propriété de dépendance existante, un scénario courant pour modifier les métadonnées de propriété de dépendance consiste à modifier la valeur par défaut. Un scénario plus avancé consiste à modifier ou ajouter des rappels de système de propriétés. Vous pouvez envisager ce scénario si votre implémentation d'une classe dérivée a des corrélations différentes entre des propriétés de dépendance. Pour avoir un modèle de programmation qui prend en charge à la fois le code et l'utilisation déclarative, 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 (JIT) sans contexte et ne peuvent pas reposer sur un ordre de paramètre, comme c'est le cas 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, mais de l'identificateur de propriété de dépendance. Par conséquent, les rappels de validation ne peuvent pas être modifiés en substituant les métadonnées.

Dans certains cas, vous souhaiterez peut-être modifier les options des métadonnées de la propriété d'infrastructure WPF sur les propriétés de dépendance existantes. Ces options communiquent certaines conditions connues à propos des propriétés d'infrastructure WPF à d'autres processus d'infrastructure WPF tels que le système de disposition. Les options sont en général définies uniquement lors de l'enregistrement d'une nouvelle propriété de dépendance, mais il est également possible de modifier les métadonnées de propriétés d'infrastructure WPF dans le cadre d'un appel OverrideMetadata ou AddOwner. Pour les valeurs spécifiques à utiliser et pour plus d'informations, consultez Métadonnées de propriété d'infrastructure. Pour plus d'informations pertinentes sur la manière dont ces options doivent être définies pour une propriété de dépendance récemment enregistrée, consultez Propriétés de dépendance personnalisées.

Substitution de métadonnées

La substitution de métadonnées a pour but principal de vous permettre de modifier les différents comportements dérivés de 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 dans plus de détail dans la section Métadonnées. Pour plus d'informations et des exemples de code, consultez Comment : 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 pouvez souhaiter fournir les métadonnées spécifiques au type pour votre classe lorsqu'elle hérite cette propriété de dépendance. Pour ce faire, appelez la méthode OverrideMetadata. Pour obtenir un exemple d'WPFAPI, la classe FrameworkElement est le type qui enregistre en premier la propriété de dépendance Focusable. Cependant, la classe Control substitue les métadonnées pour la propriété de dépendance afin de fournir sa propre valeur par défaut initiale, en la modifiant de false en true, sinon elle réutilise l'implémentation Focusable d'origine.

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

  • PropertyChangedCallback est fusionné. Si vous ajoutez un nouveau PropertyChangedCallback, ce rappel est stocké dans les métadonnées. Si vous ne spécifiez pas de PropertyChangedCallback dans la substitution, la valeur de PropertyChangedCallback est promue en tant que référence de l'ancêtre le plus proche qui l'a spécifiée dans les métadonnées.

  • Le comportement réel du système de propriétés pour PropertyChangedCallback est le suivant : des implémentations sont conservées et ajoutées à une table pour tous les propriétaires de métadonnées dans la hiérarchie et l'exécution par le système de propriétés commence par les rappels de la classe la plus dérivée.

  • DefaultValue est remplacé. Si vous ne spécifiez pas de PropertyChangedCallback dans la substitution, la valeur de DefaultValue est prise dans l'ancêtre le plus proche qui l'a spécifiée dans les métadonnées.

  • Les implémentations de CoerceValueCallback sont remplacées. Si vous ajoutez un nouveau CoerceValueCallback, ce rappel est stocké dans les métadonnées. Si vous ne spécifiez pas de CoerceValueCallback dans la substitution, la valeur de CoerceValueCallback est promue en tant que référence 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 le suivant : seul le CoerceValueCallback présent dans les métadonnées immédiates est appelé. Aucune référence à d'autres implémentations de CoerceValueCallback dans la hiérarchie n'est conservée.

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

Substitution de métadonnées de propriété attachée

Dans WPF, les propriétés attachées sont implémentées comme des propriétés de dépendance. Cela signifie qu'elles ont également des métadonnées de propriété, que des classes individuelles peuvent substituer. Les considérations sur la portée pour une propriété attachée dans WPF sont en général les suivantes : tout DependencyObject peut avoir un jeu de propriétés attachées. Par conséquent, toute classe DependencyObject dérivée peut substituer les métadonnées de toute propriété attachée, puisqu'elle peut être définie sur une instance de la classe. Vous pouvez substituer des valeurs par défaut, des rappels ou des propriétés de rapport de caractéristiques au niveau de l'infrastructure WPF. Si la propriété attachée est définie sur une instance de votre classe, ces caractéristiques de substitution des métadonnées de propriété s'appliquent. Par exemple, vous pouvez substituer la valeur par défaut, de manière à ce que votre valeur de substitution soit signalée comme valeur de la propriété attachée sur les instances de votre classe, sauf si la propriété est définie différemment.

Remarque :

La propriété Inherits n'est pas pertinente pour les propriétés attachées.

Ajout d'une classe comme propriétaire d'une propriété de dépendance existante

Une classe peut s'ajouter comme propriétaire d'une propriété de dépendance qui a déjà été enregistrée, en utilisant la méthode AddOwner. Cela permet à la classe d'utiliser une propriété de dépendance initialement enregistrée pour un autre type. La classe d'ajout n'est pas en général une classe dérivée du type qui a enregistré en premier cette propriété de dépendance comme propriétaire. En effet, cela permet à votre classe et à ses classes dérivées d'« hériter » une implémentation de propriété de dépendance sans la classe propriétaire d'origine et la classe d'ajout située dans la même hiérarchie réelle de classes. De plus, la classe d'ajout (et toutes les classes dérivées) peut fournir ensuite les métadonnées spécifiques au type pour la propriété de dépendance d'origine.

En plus de s'ajouter comme propriétaire à l'aide 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 faire de la propriété de dépendance un participant à part entière du système de propriétés avec exposition au code et au balisage. Une classe qui ajoute une propriété de dépendance existante a les mêmes responsabilités en matière d'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 type à exposer est un champ d'identificateur de propriété de dépendance. Ce champ doit être un champ public static readonly de type DependencyProperty, assigné à la valeur de retour de l'appel AddOwner. Le deuxième membre à définir est la propriété de « wrapper » Common Language Runtime (CLR). Le wrapper permet de manipuler plus facilement votre propriété de dépendance dans le code (vous évitez chaque fois des appels à SetValue et pouvez établir cet appel une seule fois dans le wrapper lui-même). Le wrapper est implémenté exactement comme il le serait si vous enregistriez 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 Comment : ajouter un type propriétaire d'une propriété de dépendance.

AddOwner et les propriétés attachées

Vous pouvez appeler AddOwner pour une propriété de dépendance définie comme propriété attachée par la classe propriétaire. En général, vous le faites pour exposer la propriété précédemment attachée comme propriété de dépendance non attachée. Vous exposerez alors la valeur de retour AddOwner comme un champ public static readonly afin de l'utiliser comme identificateur de propriété de dépendance, et vous définirez des propriétés de wrapper appropriées afin que la propriété apparaisse dans la table de membres et prenne en charge une utilisation de propriété non attachée dans votre classe.

Afficher: