Vue d'ensemble des propriétés attachées

Mise à jour : novembre 2007

Une propriété attachée est un concept défini par le XAML (Extensible Application Markup Language). Elle est conçue pour être utilisée comme un type de propriété globale qui peut être défini sur tout objet. Dans Windows Presentation Foundation (WPF), les propriétés attachées sont généralement définies comme une forme spécialisée de propriété de dépendance qui n'a pas le "wrapper" de propriété classique.

Cette rubrique comprend les sections suivantes.

  • Composants requis
  • Pourquoi utiliser des propriétés attachées
  • Propriétés attachées en XAML
  • Comment les propriétés attachées sont utilisées par le type propriétaire
  • Propriétés attachées dans le code
  • Métadonnées de propriété attachée
  • Propriétés attachées personnalisées
  • En savoir plus sur les propriétés attachées
  • Rubriques connexes

Composants requis

Cette rubrique suppose que vous compreniez 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 ayez lu Vue d'ensemble des propriétés de dépendance. Pour suivre les exemples dans cette rubrique, vous devez également comprendre le XAML (Extensible Application Markup Language) et savoir comment écrire des applications WPF.

Pourquoi utiliser des propriétés attachées

Une des finalités d'une propriété attachée est de permettre à différents éléments enfants de spécifier des valeurs uniques pour une propriété définie en fait dans un élément parent. Une application spécifique de ce scénario est de faire en sorte que les éléments enfants informent l'élément parent sur la manière dont ils doivent être présentés dans interface utilisateur (UI). La propriété DockPanel.Dock en est un exemple. La propriété DockPanel.Dock est créée comme une propriété attachée car elle est conçue pour être définie sur les éléments contenus dans un DockPanel, plutôt que sur le DockPanel proprement dit. La classe DockPanel définit le champ statique DependencyProperty nommé DockProperty, puis fournit les méthodes GetDock et SetDock comme accesseurs publics pour la propriété attachée.

Propriétés attachées en XAML

En XAML, vous définissez des propriétés attachées à l'aide de la syntaxe AttachedPropertyProvider.PropertyName.

L'exemple suivant illustre la manière dont vous pouvez définir DockPanel.Dock en XAML :

<DockPanel>
  <CheckBox DockPanel.Dock="Top">Hello</CheckBox>
</DockPanel>

Notez que l'utilisation est quelque peu semblable à une propriété statique ; vous faites toujours référence au type DockPanel qui possède et enregistre la propriété attachée, plutôt qu'à une instance quelconque spécifiée par nom.

En outre, du fait qu'une propriété attachée en XAML est un attribut que vous définissez dans les balises, seule l'opération définie est pertinente. Il n'est pas possible d'obtenir directement une propriété en XAML, bien que des mécanismes indirects permettent de comparer des valeurs, telles que les déclencheurs dans les styles (pour plus d'informations, consultez Application d'un style et création de modèles).

Implémentation des propriétés attachées dans WPF

Dans Windows Presentation Foundation (WPF), la plupart des propriétés attachées existant sur les types WPF sont implémentées comme des propriétés de dépendance. Les propriétés attachées sont un concept XAML, tandis que les propriétés de dépendance sont un concept WPF. Étant donné que les propriétés attachées WPF sont des propriétés de dépendance, elles prennent en charge les concepts des propriétés de dépendance tels que les métadonnées de propriété et les valeurs par défaut de ces métadonnées.

Comment les propriétés attachées sont utilisées par le type propriétaire

Bien que les propriétés attachées puissent être définies sur tout objet, cela ne signifie pas systématiquement que leur définition produira un résultat concret ou que leur valeur sera jamais utilisée par un autre objet. En général, les propriétés attachées sont utilisées pour que les objets provenant de diverses relations logiques ou hiérarchies de classes possibles puissent chacun communiquer des informations communes au type propriétaire. Le type qui définit la propriété attachée suit en général l'un de ces modèles :

  • Le type qui définit la propriété attachée est conçu pour pouvoir être l'élément parent des éléments qui définiront les valeurs de la propriété attachée. Le type itère ensuite ses éléments enfants à travers la logique interne, obtient les valeurs et agit sur ces valeurs de quelque manière que ce soit.

  • Le type qui définit la propriété attachée sera utilisé comme élément enfant pour divers éléments parents et modèles de contenu possibles.

  • Le type qui définit la propriété attachée représente un service. D'autres types définissent les valeurs de la propriété attachée. Lorsque l'élément qui définit la propriété est évalué dans le contexte du service, les valeurs de la propriété attachée sont alors obtenues par le biais de la logique interne de la classe de service.

Exemple d'une propriété attachée définie par le parent

Le scénario le plus courant dans lequel WPF définit une propriété attachée est lorsqu'un élément parent prend en charge une collection d'éléments enfants, et implémente également un comportement dont les caractéristiques sont signalées individuellement pour chaque élément enfant.

DockPanel définit la propriété attachée DockPanel.Dock, et le code du niveau de classe de DockPanel fait partie de la logique de rendu correspondante (en particulier MeasureOverride et ArrangeOverride). Une instance DockPanel vérifiera toujours si l'un de ses éléments enfants immédiats a défini une valeur pour DockPanel.Dock. Si tel est le cas, ces valeurs sont entrées pour la logique de rendu appliquée à l'élément enfant en question. Chaque instance imbriquée DockPanel traite ses propres collections d'éléments enfants immédiates, mais ce comportement est spécifique à l'implémentation. Il est théoriquement possible d'avoir des propriétés attachées qui influencent des éléments au-delà du parent immédiat. Si la propriété attachée DockPanel.Dock est définie sur un élément qui n'a aucun élément parent DockPanel pour agir dessus, aucune erreur ou exception n'est déclenchée. Cela signifie simplement qu'une valeur de propriété globale a été définie, mais elle n'a actuellement aucun parent DockPanel susceptible de consommer les informations.

Propriétés attachées dans le code

Les propriétés attachées dans WPF n'ont pas les méthodes de "wrapper" CLR typiques qui facilitent la définition/l'obtention de l'accès. Cela est dû au fait que la propriété attachée ne fait pas nécessairement partie de l'espace de noms CLR pour les instances dans lesquelles est définie la propriété. Toutefois, un lecteur XAML doit être en mesure de définir ces valeurs lorsque du XAML est traité. Pour être une propriété attachée effective, le type de propriétaire de la propriété attachée doit implémenter des méthodes d'accesseur dédiées au format GetPropertyName et SetPropertyName. Ces méthodes d'accesseur dédiées permettent également d'obtenir ou de définir la propriété attachée dans le code. Du point de vue du code, une propriété attachée s'apparente à un champ de stockage comportant des accesseurs de méthode au lieu d'accesseurs de propriété, et ce champ de stockage peut exister sur tout objet plutôt que devoir être défini de manière spécifique.

L'exemple suivant illustre la définition d'une propriété attachée dans le code. Dans cet exemple, myCheckBox est une instance de la classe CheckBox.

DockPanel myDockPanel = new DockPanel();
CheckBox myCheckBox = new CheckBox();
myCheckBox.Content = "Hello";
myDockPanel.Children.Add(myCheckBox);
DockPanel.SetDock(myCheckBox, Dock.Top);

Similaire au cas du XAML, si myCheckBox n'a pas déjà été ajouté comme un élément enfant de myDockPanel par la troisième ligne du code, la quatrième ligne du code ne déclenchera pas d'exception, mais la valeur de la propriété n'interagira pas avec un parent DockPanel et donc n'aura aucun impact. Seule une valeur DockPanel.Dock définie sur un élément enfant combiné à la présence d'un élément parent DockPanel déclenchera un comportement effectif dans l'application rendue.

Métadonnées de propriété attachée

Lors de l'enregistrement de la propriété, FrameworkPropertyMetadata est défini pour spécifier des caractéristiques de la propriété, par exemple si la propriété affecte le rendu, les mesures, etc. Les métadonnées d'une propriété attachée sont en général identiques à celles d'une propriété de dépendance. Si vous spécifiez une valeur par défaut dans une substitution des métadonnées d'une propriété attachée, cette valeur devient la valeur par défaut de la propriété attachée implicite sur les instances de la classe prioritaire. Spécifiquement, votre valeur par défaut est signalée si un processus demande la valeur d'une propriété attachée par le biais de l'accesseur de méthode Get de cette propriété, en spécifiant une instance de la classe dans laquelle vous avez indiqué les métadonnées, et si la valeur de cette propriété attachée n'était autrement pas définie.

Si vous souhaitez activer l'héritage des valeurs de propriété sur une propriété, vous devez utiliser des propriétés attachées plutôt que des propriétés de dépendance non attachées. Pour plus d'informations, consultez Héritage de la valeur de propriété.

Propriétés attachées personnalisées

Quand créer une propriété attachée

Vous pouvez créer une propriété attachée si un mécanisme de définition de propriété doit être disponible pour les classes autres que la classe de définition. Le scénario le plus courant à cette fin est la mise en page. Voici quelques exemples de propriétés de mise en page existantes : DockPanel.Dock, Panel.ZIndex et Canvas.Top. Le scénario activé ici implique que les éléments existant comme éléments enfants sur les éléments contrôlant la mise en page sont en mesure d'exprimer individuellement des spécifications de mise en page à leurs éléments parents de mise en page et chacun d'eux définit une valeur de propriété configurée par le parent comme une propriété attachée.

Un autre scénario illustrant l'utilisation d'une propriété attachée s'applique lorsque votre classe représente un service et vous que voulez que les classes soient en mesure d'intégrer le service avec une plus grande transparence.

Un autre scénario encore consiste à bénéficier de la prise en charge du Concepteur WPF de Visual Studio 2008, par exemple l'édition de la fenêtre Propriétés. Pour plus d'informations, consultez Vue d'ensemble de la création de contrôles.

Comme mentionné précédemment, vous devez enregistrer une propriété attachée si vous souhaitez utiliser l'héritage des valeurs de propriété.

Comment créer une propriété attachée

Si votre classe définit strictement la propriété attachée pour son utilisation sur d'autres types, il n'est alors pas nécessaire qu'elle dérive de DependencyObject. En revanche, elle doit dériver de DependencyObject si vous suivez le modèle WPF global, qui implique que votre propriété attachée soit également une propriété de dépendance.

Définissez votre propriété attachée comme une propriété de dépendance en déclarant un champ publicstaticreadonly de type DependencyProperty. Vous définissez ce champ à l'aide de la valeur de retour de la méthode RegisterAttached. Le nom du champ doit correspondre au nom de la propriété attachée, auquel s'ajoute la chaîne Property, pour suivre le modèle WPF établi de dénomination des champs d'identification par rapport aux propriétés représentés. Le fournisseur de la propriété attachée doit également fournir les méthodes statiques GetPropertyName et SetPropertyName comme accesseurs de la propriété attachée ; s'il ne fournit pas ces méthodes, le système de propriétés ne pourra pas utiliser votre propriété attachée.

Accesseur Get

La signature de l'accesseur GetPropertyName doit être la suivante :

public static object GetPropertyName(object target)

  • L'objet target peut être spécifié comme un type plus spécifique dans votre implémentation. Par exemple, la méthode DockPanel.GetDock tape le paramètre comme UIElement, car la propriété attachée doit uniquement être définie sur les instances UIElement.

  • La valeur de retour peut être spécifiée comme un type plus spécifique dans votre implémentation. Par exemple, la méthode GetDock le tape comme Dock, car la valeur peut être uniquement cette énumération.

Accesseur Set

La signature de l'accesseur SetPropertyName doit être la suivante :

public static void SetPropertyName(object target, object value)

  • L'objet target peut être spécifié comme un type plus spécifique dans votre implémentation. Par exemple, la méthode SetDock le tape comme UIElement, car la propriété attachée doit uniquement être définie sur les instances UIElement.

  • L'objet value peut être spécifié comme un type plus spécifique dans votre implémentation. Par exemple, la méthode SetDock le tape comme Dock, car la valeur peut être uniquement cette énumération. N'oubliez pas que la valeur de cette méthode est l'entrée provenant du chargeur XAML lorsqu'il rencontre votre propriété attachée dans une utilisation de celle-ci dans la balise. Cette entrée est la valeur spécifiée comme une valeur d'attribut XAML dans la balise. Par conséquent, la conversion de type, la sérialisation de valeur ou l'extension de balisage doit être prise en charge pour le type utilisé de sorte que le type approprié puisse être créé à partir de la valeur d'attribut (laquelle est en fin de compte une simple chaîne).

L'exemple suivant illustre l'enregistrement de la propriété de dépendance (à l'aide de la méthode RegisterAttached) ainsi que des accesseurs GetPropertyName et SetPropertyName. Dans cet exemple, le nom de la propriété attachée est IsBubbleSource. Par conséquent, les accesseurs doivent être nommés GetIsBubbleSource et SetIsBubbleSource.

public static readonly DependencyProperty IsBubbleSourceProperty = DependencyProperty.RegisterAttached(
  "IsBubbleSource",
  typeof(Boolean),
  typeof(AquariumObject),
  new FrameworkPropertyMetadata(false, FrameworkPropertyMetadataOptions.AffectsRender)
);
public static void SetIsBubbleSource(UIElement element, Boolean value)
{
  element.SetValue(IsBubbleSourceProperty, value);
}
public static Boolean GetIsBubbleSource(UIElement element)
{
  return (Boolean)element.GetValue(IsBubbleSourceProperty);
}

Attributs des propriétés attachées

WPF définit plusieurs attributs .NET Framework qui doivent fournir des informations sur les propriétés attachées aux processus de réflexion et aux utilisateurs typiques des informations de réflexion et de propriété, tels que les concepteurs. Étant donné que le type des propriétés attachées a une portée illimitée, les concepteurs doivent pouvoir éviter d'accabler les utilisateurs avec une liste globale de toutes les propriétés attachées définies dans une implémentation technologique particulière qui utilise le XAML. Le attributs .NET Framework que WPF définit pour les propriétés attachées peut être utilisé pour déterminer les cas où une propriété attachée donnée doit être affichée dans une fenêtre de propriétés. Vous pouvez également envisager l'application de ces attributs à vos propres propriétés attachées personnalisées. La finalité et la syntaxe de attributs .NET Framework sont décrites dans les pages de référence appropriées :

En savoir plus sur les propriétés attachées

  • Pour plus d'informations sur la création d'une propriété attachée, consultez Comment : enregistrer une propriété attachée.

  • Pour obtenir des scénarios d'usage avancés des propriétés de dépendance et des propriétés attachées, consultez Propriétés de dépendance personnalisées.

  • Vous pouvez également enregistrer une propriété comme une propriété attachée et comme une propriété de dépendance ; mais dans ce cas, vous exposerez encore les implémentations de "wrapper." Dans ce cas, la propriété peut avoir pour valeur cet élément ou tout élément inclus dans la syntaxe de la propriété attachée XAML. Le scénario suivant illustre un exemple de propriété pour utilisations standard et attachée : FrameworkElement.FlowDirection.

Voir aussi

Tâches

Comment : enregistrer une propriété attachée

Concepts

Vue d'ensemble des propriétés de dépendance

Propriétés de dépendance personnalisées

Vue d'ensemble du langage XAML

Référence

DependencyProperty