Syntaxe XAML en détail

Cette rubrique définit les termes utilisés pour décrire les éléments de la syntaxe XAML. Ces termes sont fréquemment utilisés tout au long de la suite de cette documentation, à la fois pour la documentation WPF spécifiquement et pour les autres infrastructures qui utilisent XAML ou les concepts XAML de base activés par la prise en charge du langage XAML au niveau de System.Xaml. Cette rubrique décrit plus en détail la terminologie de base introduite dans la rubrique Vue d'ensemble du langage XAML (WPF).

Cette rubrique comprend les sections suivantes.

  • Spécification de langage XAML
  • XAML et CLR
  • Syntaxe des éléments objet
  • Propriétés des éléments objet
  • Syntaxe d'attribut (propriétés)
  • Syntaxe des éléments de propriété
  • Syntaxe de collection
  • Propriétés de contenu XAML
  • Propriétés de contenu et syntaxe de collection combinées
  • Espaces de noms XAML
  • Extensions de balisage
  • Propriétés jointes
  • Événements attachés
  • Anatomie d'un élément racine XAML
  • Utilisations facultatives et non recommandées de XAML
  • Rubriques connexes

Spécification de langage XAML

La terminologie de syntaxe XAML définie ici est également définie ou référencée dans la spécification de langage XAML. XAML est un langage basé sur XML qui suit les règles structurelles de XML ou se développe à partir de ces dernières. Une partie de la terminologie est commune à ou basée sur la terminologie communément utilisée pour la description du langage XML ou du modèle d'objet de document XML.

Pour plus d'informations sur la spécification de langage XAML, téléchargez [MS-XAML] à partir du Centre de téléchargement Microsoft.

XAML et CLR

XAML est un langage de balisage. common language runtime (CLR), comme son nom l'indique, autorise l'exécution (runtime). XAML à proprement parler n'est pas l'un des langages habituels consommés directement par le runtime CLR. Considérez plutôt XAML comme un langage prenant en charge son propre système de type. Le système d'analyse XAML particulier utilisé par WPF repose sur CLR et le système de type CLR. Les types XAML sont mappés aux types CLR pour instancier une représentation au moment de l'exécution lorsque le XAML pour WPF est analysé. Pour cette raison, le reste de la présentation de la syntaxe dans ce document comprend des références au système de type CLR, bien que les discussions équivalentes à propos de la syntaxe dans la spécification de langage XAML ne le fassent pas. (Selon le niveau de spécification du langage XAML, les types XAML peuvent être mappés à tout autre système de type (autre que CLR) mais cela nécessiterait la création et l'utilisation d'un analyseur XAML différent.)

Membres de types et héritage de classe

Les propriétés et événements tels qu'ils s'affichent sous la forme de membres XAML d'un type WPF sont souvent hérités de types de base. Par exemple, observez ce qui suit : <Button Background="Blue" .../>. La propriété Background n'est pas une propriété déclarée immédiatement sur la classe Button, si vous regardez la définition de classe, les résultats de réflexion ou la documentation. La propriété Background est en fait héritée de la classe Control.

Le comportement d'héritage de classe des éléments XAML WPF est une autre nouveauté majeure par rapport à l'interprétation à partir de schémas du balisage XML. L'héritage de classe peut devenir complexe, en particulier lorsque les classes de base intermédiaires sont abstraites, ou lorsque les interfaces sont impliquées. Il s'agit de l'une des raisons pour lesquelles le jeu d'éléments XAML et leurs attributs autorisés sont difficiles à représenter de manière précise et complète à l'aide des types de schéma généralement utilisés pour la programmation XML, tels que le format DTD ou XSD. Une autre raison tient au fait que les fonctionnalités d'extensibilité et de mappage de type du langage XAML lui-même empêchent toute représentation fixe exhaustive des types et membres autorisés.

Syntaxe des éléments objet

La syntaxe des éléments objet est la syntaxe de balisage XAML qui instancie une structure ou une classe CLR en déclarant un élément XML. Cette syntaxe ressemble à la syntaxe des éléments d'autres langages de balisage, tels que HTML. La syntaxe des éléments objet commence par le signe « inférieur à » (<), immédiatement suivi par le nom du type de classe ou de structure instanciée. Un zéro ou d'autres espaces peuvent suivre le nom du type, et un zéro ou d'autres attributs peuvent également être déclarés dans l'élément objet, avec un ou plusieurs espaces séparant chaque paire nom d'attribut="valeur". Enfin, l'une des conditions suivantes doit être satisfaite :

  • L'élément et la balise doivent être fermés par une barre oblique (/), suivie immédiatement par le signe « supérieur à » (>).

  • La balise ouvrante doit être complétée par le signe « supérieur à » (>). D'autres éléments objet, éléments de propriété ou texte interne peuvent suivre cette balise. La nature exacte du contenu susceptible d'être utilisé ici est généralement limitée par le modèle objet de l'élément. La balise fermante équivalente de l'élément objet doit également exister et elle doit être correctement imbriquée et équilibrée avec les autres paires de balises ouvrantes et fermantes.

XAML tel qu"il est implémenté par .NET dispose d'un jeu des règles qui mappent les éléments objet dans des types, les attributs dans des propriétés ou des événements, et les espaces de noms XAML aux espaces de noms CLR et aux assemblys. Pour WPF et le .NET Framework, les éléments objet XAML sont mappés aux types Microsoft .NET comme défini dans les assemblys référencés, et les attributs sont mappés aux membres de ces types. Lorsque vous référencez un type CLR en XAML, vous avez également accès aux membres hérités de ce type.

L'exemple suivant illustre la syntaxe d'un élément objet qui instancie une nouvelle instance de la classe Button et spécifie également un attribut Name et la valeur de cet attribut :

<Button Name="CheckoutButton"/>

L'exemple suivant illustre la syntaxe d'un élément objet qui comprend également la syntaxe de la propriété de contenu XAML. Le texte interne qui y est contenu sera utilisé pour définir la propriété de contenu XAML TextBox, Text.

<TextBox>This is a Text Box</TextBox>

Modèles de contenu

Une classe peut prendre en charge une utilisation en tant qu'élément objet XAML d'un point de vue syntaxique, mais cet élément ne fonctionnera correctement dans une application ou une page que s'il est placé à un emplacement attendu d'un modèle de contenu général ou d'une arborescence d'éléments. Par exemple, un MenuItem ne peut généralement être placé qu'en tant qu'enfant d'une classe dérivée MenuBase telle que Menu. Les modèles de contenu d'éléments spécifiques sont documentés dans le cadre des notes sur les pages de classe pour les contrôles et d'autres classes WPF pouvant être utilisées comme éléments XAML.

Propriétés des éléments objet

Les propriétés en XAML sont définies par diverses syntaxes possibles. La syntaxe susceptible d'être utilisée pour une propriété particulière varie selon les caractéristiques du système de type sous-jacent de la propriété que vous définissez.

En définissant des valeurs de propriétés, vous ajoutez des fonctionnalités ou des caractéristiques aux objets comme ils existent dans le graphique d'objet au moment de l'exécution. L'état initial de l'objet créé d'un élément objet est fonction du comportement du constructeur par défaut. Votre application évitera généralement d'utiliser une instance entièrement par défaut d'un objet donné.

Syntaxe d'attribut (propriétés)

La syntaxe d'attribut est la syntaxe de balisage XAML qui définit une valeur pour une propriété en déclarant un attribut sur un élément objet existant. Le nom de l'attribut doit correspondre au nombre de membre CLR de la propriété de la classe qui stocke l'élément objet concerné. Il est suivi d'un opérateur d'assignation (=). La valeur d'attribut doit être une chaîne entre guillemets.

RemarqueRemarque

Vous pouvez utiliser d'autres guillemets pour placer un guillemet littéral dans un attribut.Par exemple, vous pouvez utiliser des guillemets simples pour déclarer une chaîne qui contient des guillemets doubles.Que vous utilisiez des guillemets simples ou doubles, vous devez utiliser une paire correspondante pour l'ouverture et la fermeture de la chaîne de valeur d'attribut.Il existe aussi des séquences d'échappement ou d'autres techniques disponibles pour contourner les restrictions de caractères imposées par toute syntaxe XAML particulière.Consultez Entités de caractères XML et XAML.

Pour être définie via la syntaxe des attributs, une propriété doit être publique et accessible en écriture. La valeur de la propriété dans le système de types de stockage doit être un type valeur, ou un type référence qui peut être instancié ou référencé par un processeur XAML lors de l'accès au type de stockage pertinent.

Pour les événements XAML WPF, l'événement référencé en tant que nom de l'attribut doit être public et avoir un délégué public.

La propriété ou l'événement doit être membre de la classe ou de la structure instanciée par l'élément objet contenant.

Traitement des valeurs d'attribut

La valeur de chaîne contenue entre les guillemets anglais ouvrants et fermants est traitée par un processeur XAML. Pour les propriétés, le comportement de traitement par défaut est déterminé par le type de la propriété CLR sous-jacente.

La valeur d'attribut est renseignée de l'une des manières suivantes, en suivant cet ordre de traitement :

  1. Si le processeur XAML rencontre une accolade, ou un élément objet dérivé de MarkupExtension, l'extension de balisage référencée est alors évaluée en premier, plutôt que de traiter la valeur comme une chaîne, et l'objet qu'elle renvoie est utilisé comme valeur. Dans de nombreux cas, l'objet renvoyé par une extension de balisage sera une référence à un objet existant ou une expression qui diffère l'évaluation jusqu'au moment de l'exécution, et non un objet nouvellement instancié.

  2. Si la propriété est déclarée avec un TypeConverter attribué ou que le type valeur de cette propriété est déclaré avec un TypeConverter attribué, la valeur de chaîne de l'attribut est transmise au convertisseur de type en tant qu'entrée de conversion et ce dernier renverra une nouvelle instance d'objet.

  3. S'il n'existe aucune TypeConverter, une conversion directe dans le type de propriété est tentée. Ce dernier niveau est une conversion directe à la valeur native de l'analyseur entre des types primitifs de langage XAML, ou un contrôle des noms de constantes nommées dans une énumération (l'analyseur accède ensuite aux valeurs correspondantes).

Valeurs d'attribut d'énumération

Les énumérations en XAML sont traitées intrinsèquement par les analyseurs XAML, et les membres d'une énumération doivent être spécifiés en spécifiant le nom de chaîne de l'une des constantes nommées de l'énumération.

Pour les valeurs d'énumération ne comportant pas d'indicateurs, le comportement natif consiste à traiter la chaîne d'une valeur d'attribut et à la résoudre en l'une des valeurs d'énumération. Vous ne spécifiez pas l'énumération au format Enumeration.Value, comme c'est le cas dans le code. Vous spécifiez plutôt la Valeur seulement et l'Énumération est déduite par le type de la propriété définie. Si vous spécifiez un attribut au format Enumeration.Value, il ne sera pas correctement résolu.

Pour les énumérations avec indicateur, le comportement repose sur la méthode Enum.Parse. Vous pouvez spécifier plusieurs valeurs pour une énumération avec indicateur en séparant chacune d'elles avec une virgule. Toutefois, vous ne pouvez pas combiner des valeurs d'énumération qui ne comportent pas d'indicateurs. Par exemple, vous ne pouvez pas utiliser la syntaxe de virgule pour essayer de créer un Trigger qui agisse sur plusieurs conditions d'une énumération ne comportant pas d'indicateurs :

<!--This will not compile, because Visibility is not a flagwise enumeration.-->
...
<Trigger Property="Visibility" Value="Collapsed,Hidden">
  <Setter ... />
</Trigger>
...

Les énumérations comportant des indicateurs qui prennent en charge des attributs définissables en XAML sont rares dans WPF. Toutefois, une telle énumération est StyleSimulations. Vous pourriez, par exemple, utilisez la syntaxe d'attribut comportant des indicateurs délimitée par des virgules pour modifier l'exemple fourni dans les remarques de la classe Glyphs ; StyleSimulations = "BoldSimulation" pourrait devenir StyleSimulations = "BoldSimulation,ItalicSimulation". KeyBinding.Modifiers est une autre propriété pour laquelle plusieurs valeurs d'énumération peuvent être spécifiées. Toutefois, cette propriété est un cas spécial, parce que l'énumération ModifierKeys prend en charge son propre convertisseur de type. Le convertisseur de type pour les utilisations de modificateurs utilisent un signe plus (+) en tant que délimiteur plutôt qu'une virgule (,). Cette conversion prend en charge la syntaxe plus traditionnelle pour représenter des combinaisons de touches dans la programmation Microsoft Windows, telle que « Ctrl+Alt ».

Propriétés et références de noms de membres d'événement

Lorsque vous spécifiez un attribut, vous pouvez faire référence à toute propriété ou à tout événement existant en tant que membre du type CLR instancié pour l'élément objet contenant.

Vous pouvez aussi faire référence à une propriété ou un événement attaché, indépendamment de l'élément objet contenant. (Les propriétés jointes sont abordées dans une section ultérieure.)

Vous pouvez également nommer un événement à partir d'un objet accessible via l'espace de noms par défaut à l'aide d'un nom partiellement qualifié typeName.event ; cette syntaxe prend en charge l'association de gestionnaires pour les événements routés où il est prévu que le gestionnaire gère le routage des événements à partir des éléments enfants, mais où la table des membres de l'élément parent ne contient pas non plus cet événement. Cette syntaxe ressemble à une syntaxe d'événement attaché, mais l'événement ici n'est pas un véritable événement attaché. Vous faites en fait référence à un événement avec un nom qualifié. Pour plus d'informations, consultez Vue d'ensemble des événements routés.

Dans certains scénarios, les noms de propriétés sont quelquefois fournis comme valeur d'attribut, plutôt que comme nom d'attribut. Ce nom de propriété peut également inclure des qualificateurs, tels que la propriété spécifiée dans le formulaire ownerType.dependencyPropertyName. Ce scénario est courant lors de l'écriture de styles ou de modèles en XAML. Les règles de traitement pour les noms de propriétés fournis comme valeur d'attribut sont différentes et sont gouvernées par le type de la propriété qui est définie ou par les comportements de sous-systèmes WPF particuliers. Pour plus d'informations, consultez Application d'un style et création de modèles.

Les noms de propriété sont également utilisés lorsqu'une valeur d'attribut décrit une relation entre deux propriétés. Cette fonction est utilisée pour la liaison de données et pour les cibles de storyboard et elle est activée par la classe PropertyPath et son convertisseur de type. Pour une description plus complète de la sémantique de recherche, consultez PropertyPath, syntaxe XAML.

Syntaxe des éléments de propriété

La syntaxe d'élément de propriété est une syntaxe qui diverge quelque peu des règles de syntaxe XML de base pour les éléments. En XML, la valeur d'un attribut est une chaîne de facto, la seule variante possible étant le format d'encodage de chaîne utilisé. En XAML, vous pouvez assigner d'autres éléments objet comme valeur d'une propriété. Cette fonctionnalité est activée par la syntaxe de l'élément de propriété. Au lieu d'être spécifiée comme un attribut dans la balise d'élément, la propriété est spécifiée à l'aide d'une balise d'élément ouvrante au format elementTypeName.propertyName, puis sa valeur est spécifiée et enfin l'élément de propriété est fermé.

Spécifiquement, la syntaxe commence par le signe « inférieur à » (<), suivi immédiatement par le nom du type de classe ou de structure dans laquelle est contenue la syntaxe de l'élément de propriété. Elle est suivie immédiatement d'un point unique (.), puis du nom d'une propriété, puis d'un crochet droit (>). Comme avec la syntaxe d'attribut, cette propriété doit exister dans les membres publics déclarés du type spécifié. La valeur à assigner à la propriété est contenue dans l'élément de propriété. Cette valeur est généralement donnée comme un ou plusieurs éléments objet, puisque la spécification d'objets comme des valeurs est le scénario que la syntaxe des éléments de propriété essaie de résoudre. Enfin, une balise fermante équivalente spécifiant la même combinaison elementTypeName.propertyName doit être fournie ; celle-ci doit être correctement imbriquée et équilibrée avec les autres balises d'élément.

L'exemple suivant illustre la syntaxe d'un élément de la propriété ContextMenu d'un Button.

<Button>
  <Button.ContextMenu>
    <ContextMenu>
      <MenuItem Header="1">First item</MenuItem>
      <MenuItem Header="2">Second item</MenuItem>
    </ContextMenu>
  </Button.ContextMenu>
  Right-click me!</Button>

La valeur figurant dans un élément de propriété peut également être indiquée sous forme de texte interne, dans les cas où le type de propriété qui est spécifié est un type valeur primitif (String, par exemple) ou une énumération dans laquelle un nom est spécifié. Ces deux utilisations sont quelque peu rares, étant donné que chacun de ces cas peut également utiliser une syntaxe d'attribut plus simple. Un scénario permettant de renseigner un élément de propriété avec une chaîne s'applique aux propriétés non associées au contenu XAML mais qui sont tout de même utilisées pour la représentation de texte d'interface utilisateur, et des éléments d'espace blanc particuliers, tels que des sauts de ligne, doivent apparaître dans ce texte d'interface utilisateur. La syntaxe d'attribut ne peut pas conserver les sauts de ligne, contrairement à la syntaxe des éléments de propriété, à condition que la fonction de conservation des espaces significatifs soit active (pour plus d'informations à ce sujet, consultez Traitement des espaces blancs en XAML). Un autre scénario veut que x:Uid, directive puisse être appliqué à l'élément de propriété et marque donc la valeur comme une valeur qui doit être localisée dans le BAML de la sortie WPF ou par d'autres techniques.

Un élément de propriété n'est pas représenté dans l'arborescence logique WPF. Un élément de propriété n'est qu'une syntaxe particulière permettant de définir une propriété, et non un élément qui possède une instance ou un objet. (Pour plus d'informations sur le concept d'arborescence logique, consultez Arborescences dans WPF.)

Pour les propriétés pour lesquelles la syntaxe d'attribut et la syntaxe d'élément de propriété sont toutes deux prises en charge, les deux syntaxes donnent généralement le même résultat, malgré de légères différences entre les deux (gestion des espaces blancs, par exemple).

Syntaxe de collection

La spécification XAML requiert que les implémentations de processeur XAML soient en mesure d'identifier les propriétés où le type valeur est une collection. L'implémentation de processeur XAML général dans .NET est basée sur le code managé et le CLR. Elle identifie les types de collections par le biais de l'un des éléments suivants :

Si le type d'une propriété est une collection, le type de collection déduit n'a pas besoin d'être spécifié dans le balisage en tant qu'élément objet. Au lieu de cela, les éléments qui doivent faire partie de la collection sont spécifiés comme un ou plusieurs éléments enfants de l'élément de propriété. Chacun de ces éléments est évalué en tant qu'objet pendant son chargement et est ajouté à la collection en appelant la méthode Add de la collection impliquée. Par exemple, la propriété Triggers de Style prend le type de collection TriggerCollection spécialisé, qui implémente IList. Il n'est pas nécessaire d'instancier un élément objet TriggerCollection dans le balisage. Au lieu de cela, vous spécifiez un ou plusieurs éléments Trigger comme éléments dans l'élément de propriété Style.Triggers, où Trigger (ou une classe dérivée) est le type d'élément attendu pour le TriggerCollection fortement typé et implicite.

<Style x:Key="SpecialButton" TargetType="{x:Type Button}">
  <Style.Triggers>
    <Trigger Property="Button.IsMouseOver" Value="true">
      <Setter Property = "Background" Value="Red"/>
    </Trigger>
    <Trigger Property="Button.IsPressed" Value="true">
      <Setter Property = "Foreground" Value="Green"/>
    </Trigger>
  </Style.Triggers>
</Style>

Une propriété peut être à la fois un type de collection et la propriété de contenu XAML pour ce type et les types dérivés, présentés dans la section suivante de cette rubrique.

Un élément de collection implicite crée un membre dans la représentation de l'arborescence logique, bien qu'il n'apparaisse pas dans le balisage en tant qu'élément. Habituellement, le constructeur du type parent exécute l'instanciation pour la collection qui est l'une de ses propriétés, et la collection initialement vide devient un élément de l'arborescence d'objets.

RemarqueRemarque

La liste générique et les interfaces de dictionnaires (IList<T> et IDictionary<TKey, TValue>) ne sont pas prises en charge pour la détection de collection.Toutefois, vous pouvez utiliser la classe List<T> comme classe de base, parce qu'elle implémente IList directement, ou Dictionary<TKey, TValue> comme classe de base, parce qu'elle implémente IDictionary directement.

Dans les pages .NET Reference des types de collections, cette syntaxe avec omission délibérée de l'élément objet pour une collection est parfois désignée dans les sections de syntaxe XAML en tant que syntaxe de collection implicite.

À l'exception de l'élément racine, chaque élément objet d'un fichier XAML imbriqué en tant qu'élément enfant d'un autre élément est en fait un élément d'un ou des deux types suivants : un membre d'une propriété de collection implicite de son élément parent ou un élément qui spécifie la valeur de la propriété de contenu XAML pour l'élément parent (les propriétés de contenu XAML sont abordées dans une section ultérieure). En d'autres termes, la relation d'éléments parents et d'éléments enfants dans une page de balisage est en fait un objet unique à la racine, et tous les éléments objets sous la racine sont soit des instances uniques fournissant des valeurs de propriété du parent, soit des éléments d'une collection qui sont également des valeurs de propriété de type collection du parent. Ce concept de racine unique est courant avec XML et est fréquemment renforcé dans le comportement des API qui chargent XAML, telles que Load.

L'exemple suivant est une syntaxe avec l'élément objet pour une collection (GradientStopCollection) spécifiée explicitement.

<LinearGradientBrush>
  <LinearGradientBrush.GradientStops>
    <GradientStopCollection>
      <GradientStop Offset="0.0" Color="Red" />
      <GradientStop Offset="1.0" Color="Blue" />
    </GradientStopCollection>
  </LinearGradientBrush.GradientStops>
</LinearGradientBrush>

Notez qu'il n'est pas toujours possible de déclarer la collection explicitement. Par exemple, une tentative de déclaration explicite de TriggerCollection dans l'exemple Triggers présenté précédemment échouerait. Une déclaration explicite de la collection nécessite que la classe de collection prenne en charge un constructeur par défaut et que TriggerCollection n'ait pas de constructeur par défaut.

Propriétés de contenu XAML

La syntaxe de contenu XAML est une syntaxe qui est uniquement utilisée pour les classes qui spécifient le ContentPropertyAttribute dans le cadre de leur déclaration de classe. Le ContentPropertyAttribute référence le nom de la propriété qui est la propriété de contenu pour ce type d'élément (y compris les classes dérivées). En cas de traitement par un processeur XAML, les éléments enfants ou le texte interne détectés entre les balises de fermeture et d'ouverture de l'élément objet sont assignés en tant que valeur de la propriété de contenu XAML de cet objet. Vous êtes autorisé à spécifier des éléments de propriété explicites pour la propriété de contenu, mais cette utilisation n'est pas généralement pas affichée dans les sections de syntaxe XAML dans la référence .NET. Cette technique explicite/détaillée permet parfois de clarifier le balisage ou d'indiquer un style de balisage, mais une propriété de contenu a généralement pour finalité de rationaliser le balisage de sorte que les éléments qui possèdent intuitivement un lien parents-enfants puissent être directement imbriqués. Les balises d'éléments de propriété d'autres propriétés sur un élément ne sont pas assignées en tant que « contenu », selon une définition stricte de langage XAML ; elles ont été préalablement traitées dans l'ordre de traitement de l'analyseur XAML et ne sont pas considérées comme étant du « contenu ».

Les valeurs des propriétés de contenu XAML doivent être contiguës

La valeur d'une propriété de contenu XAML doit être indiquée dans son intégralité avant ou après tous les autres éléments de propriété sur cet élément objet. Ce principe est valable que la valeur d'une propriété de contenu XAML soit spécifiée en tant que chaîne ou sous la forme d'un ou plusieurs objets. Par exemple, le balisage suivant n'analyse pas :

<Button>I am a 
  <Button.Background>Blue</Button.Background>
  blue button</Button>

Cet exemple n'est pas valide parce que si cette syntaxe était rendue explicite par l'utilisation de la syntaxe d'élément de propriété pour la propriété de contenu, cette dernière serait définie deux fois :

<Button>
  <Button.Content>I am a </Button.Content>
  <Button.Background>Blue</Button.Background>
  <Button.Content> blue button</Button.Content>
</Button>

Un exemple dans lequel la propriété de contenu est une collection et où des éléments enfants sont entrecoupés par des éléments de propriété est tout aussi incorrect :

<StackPanel>
  <Button>This example</Button>
  <StackPanel.Resources>
    <SolidColorBrush x:Key="BlueBrush" Color="Blue"/>
  </StackPanel.Resources>
  <Button>... is illegal XAML</Button>
</StackPanel>

Propriétés de contenu et syntaxe de collection combinées

Pour accepter plusieurs éléments objet comme contenu, le type de la propriété de contenu doit être spécifiquement un type de collection. De même que dans la syntaxe d'un élément de propriété pour les types de collections, un processeur XAML doit identifier les types qui sont des types de collection. Si un élément possède une propriété de contenu XAML et que le type de cette propriété de contenu XAML est une collection, le type de collection implicite n'a alors pas besoin d'être spécifié dans le balisage en tant qu'élément objet et la propriété de contenu XAML n'a pas besoin d'être spécifiée en tant qu'élément de propriété. Par conséquent, le modèle de contenu apparent dans la balise peut désormais avoir plusieurs éléments enfants assignés comme contenu. L'exemple suivant illustre la syntaxe de contenu d'une classe dérivée Panel. Toutes les classes dérivées Panel attribuent à la propriété de contenu XAML la valeur Children, qui requiert une valeur de type UIElementCollection.

<Page
  xmlns="https://schemas.microsoft.com/winfx/2006/xaml/presentation"
  xmlns:x="https://schemas.microsoft.com/winfx/2006/xaml"
  >
  <StackPanel>
    <Button>Button 1</Button>
    <Button>Button 2</Button>
    <Button>Button 3</Button>
  </StackPanel>
</Page>

Notez que ni l'élément de propriété pour Children ni l'élément pour UIElementCollection n'est requis dans la balise. Il s'agit d'une caractéristique conceptuelle du langage XAML grâce à laquelle les éléments contenus de manière récursive qui définissent une UI sont représentés de manière plus intuitive sous la forme d'une arborescence d'éléments imbriqués avec des relations parent/enfant immédiates, sans l'intervention de balises d'élément de propriété ou d'objets de collection. En fait, UIElementCollection ne peut pas être spécifié explicitement dans le balisage en tant qu'élément objet, par conception. Du fait qu'il n'est prévu qu'il soit utilisé que comme une collection implicite, UIElementCollection n'expose pas de constructeur public par défaut et, par conséquent, ne peut pas être instancié comme un élément objet.

Combinaison d'éléments de propriété et d'éléments objet dans un objet avec une propriété de contenu

La spécification XAML déclare qu'un processeur XAML peut appliquer une règle exigeant que les éléments objet utilisés pour renseigner la propriété de contenu XAML dans un élément objet soient contigus et ne doivent pas être combinés. Cette règle interdisant la combinaison d'éléments de propriété et de contenu est appliquée par les processeurs XAML WPF.

Vous pouvez avoir un élément objet enfant comme première balise immédiate dans un élément objet. Vous pouvez ensuite introduire des éléments de propriété. Vous pouvez aussi spécifier un ou plusieurs éléments de propriété, puis un contenu, puis d'autres éléments de propriété. Mais une fois qu'un élément de propriété suit le contenu, vous ne pouvez plus introduire d'autre contenu, mais uniquement ajouter des éléments de propriété.

Cet ordre exigé contenu/élément de propriété ne s'applique pas au texte interne utilisé comme contenu. Toutefois, il reste recommandé de garder le texte interne contigu car il sera difficile de détecter visuellement l'espace significatif dans les balises si des éléments de propriété sont intercalés avec le texte interne.

Espaces de noms XAML

Aucun des exemples de syntaxe précédents n'a spécifié d'espace de noms XAML autre que l'espace de noms XAML par défaut. Dans les applications WPF typiques, l'espace de noms XAML par défaut est spécifié comme étant l'espace de noms WPF. Vous pouvez spécifier des espaces de noms XAML différents de l'espace de noms XAML par défaut et encore utiliser la même syntaxe. En revanche, ce nom de classe doit être précédé du préfixe de l'espace de noms XAML comme il a été mappé à l'espace de noms CLR correspondant s'il est situé à un endroit, où une classe est nommée, qui n'est pas accessible dans l'espace de noms XAML par défaut. Par exemple, <custom:Example/> est la syntaxe de l'élément objet servant à instancier une instance de la classe Example, où l'espace de noms CLR contenant cette classe (et éventuellement les informations d'assemblys externes contenant les types de stockage) a été précédemment mappé au préfixe custom.

Pour plus d'informations sur les espaces de noms XAML, consultez Espaces de noms XAML et mappage d'espace de noms pour XAML WPF.

Extensions de balisage

XAML définit une entité de programmation d'extensions de balisage qui permet d'échapper au traitement normal des valeurs d'attribut de chaîne ou des éléments objet par le processeur XAML, et qui diffère le traitement vers une classe de stockage. Le caractère qui identifie une extension de balisage sur un processeur XAML lors de l'utilisation de la syntaxe d'attribut est l'accolade ouvrante ({), suivie de tout caractère autre qu'une accolade fermante (}). La première chaîne qui suit l'accolade ouvrante doit faire référence à la classe qui fournit le comportement d'extension particulier, où la référence peut omettre la sous-chaîne "Extension" si celle-ci fait partie du nom de classe véritable. Un espace unique peut apparaître ensuite, puis chaque caractère successif est utilisé comme entrée par l'implémentation d'extension, jusqu'à rencontrer l'accolade fermante.

L'implémentation XAML .NET utilise la classe abstraite MarkupExtension comme base pour toutes les extensions de balisage prises en charge par WPF ainsi que d'autres infrastructures ou technologies. Les extensions de balisage que WPF implémente spécifiquement sont souvent destinées à fournir un moyen de faire référence à d'autres objets existants, ou d'effectuer des références différées aux objets qui seront évalués au moment de l'exécution. Par exemple, une liaison de données WPF simple est accomplie en spécifiant l'extension de balisage {Binding} au lieu de la valeur qu'une propriété particulière aurait normalement. De nombreuses extensions de balisage WPF permettent d'utiliser une syntaxe d'attribut pour des propriétés qui, autrement, n'accepteraient pas cette syntaxe. Par exemple, un objet Style est un type relativement complexe qui contient une série imbriquée d'objets et de propriétés. Les styles dans WPF sont généralement créés comme une ressource dans une ResourceDictionary, puis ils sont référencés par le biais de l'une des deux extensions de balisage qui requièrent une ressource. L'extension de balisage soumet l'évaluation de la valeur de la propriété à une recherche de ressource et permet de fournir la valeur de la propriété Style, en prenant le type Style, dans la syntaxe d'attribut comme dans l'exemple suivant :

<Button Style="{StaticResource MyStyle}">My button</Button>

Dans cet exemple, StaticResource identifie la classe StaticResourceExtension qui fournit l'implémentation de l'extension de balisage. La chaîne MyStyle suivante est utilisée comme entrée pour le constructeur StaticResourceExtension non défini par défaut, où le paramètre récupéré depuis la chaîne d'extension déclare le ResourceKeydemandé. MyStyle est supposé être la valeur x:Key d'un Style défini en tant que ressource. L'utilisation de StaticResource, extension de balisage demande que la ressource soit utilisée pour fournir la valeur de propriété Style par le biais de la logique de recherche de ressource statique logique au moment du chargement.

Pour plus d'informations sur les extensions de balisage, consultez Extensions de balisage et XAML WPF. Pour une référence d'extensions de balisage et d'autres fonctionnalités de programmation XAML activée dans l'implémentation XAML .NET générale, consultez Fonctionnalités de langage pour les espaces de noms XAML (x:). Pour les extensions de balisage spécifiques à WPF, consultez Extensions XAML WPF.

Propriétés jointes

Les propriétés jointes sont un concept de programmation ajouté à XAML via lequel les propriétés peuvent être possédées et définies par un type particulier, mais définies en tant qu'attributs ou éléments de propriété sur n'importe quel élément. Le principal scénario auquel sont destinées les propriétés jointes consiste à permettre aux éléments enfants d'une structure de balisage de signaler des informations à un élément parent sans nécessiter de modèle objet largement partagé entre tous les éléments. À l'inverse, les propriétés attachées peuvent être utilisées par les éléments parents pour signaler des informations aux éléments enfants. Pour plus d'informations sur la finalité des propriétés attachées et pour savoir comment créer vos propres propriétés attachées, consultez Vue d'ensemble des propriétés jointes.

Les propriétés attachées utilisent une syntaxe qui, en apparence, ressemble à la syntaxe des éléments de propriété dans la mesure où vous spécifiez également une combinaison typeName.propertyName. Il existe deux différences majeures :

  • Vous pouvez même utiliser la combinaison typeName.propertyName lors de la définition d'une propriété attachée par le biais de la syntaxe d'attribut. Les propriétés attachées sont le seul cas où la qualification du nom de propriété est exigée dans une syntaxe d'attribut.

  • Vous pouvez également utiliser la syntaxe des éléments de propriété pour les propriétés attachées. Toutefois, dans la syntaxe typique d'un élément de propriété, le typeName que vous spécifiez est l'élément objet contenant l'élément de propriété. Si vous faites référence à une propriété attachée, le typeName est la classe qui définit la propriété attachée, pas l'élément objet contenant.

Événements attachés

Les événements attachés sont un autre concept de programmation XAML via lequel les événements peuvent être définis par un type spécifique et les gestionnaires peuvent être joints à tout élément objet. Dans l'implémentation WOF, le type qui définit un événement attaché est souvent un type statique définissant un service, et ces événements attachés sont parfois exposés par un alias d'événement routé dans les types qui exposent le service. Les gestionnaires des événements attachés sont spécifiés dans la syntaxe d'attribut. Comment pour les événements attachés, la syntaxe d'attribut est développée afin de permettre l'utilisation d'un typeName.eventName, où typeName est la classe qui fournit les accesseurs de gestionnaire d'événements Add et Remove de l'infrastructure des événements attachés et où eventName est le nom de l'événement.

Anatomie d'un élément racine XAML

Le tableau suivant montre un élément racine XAML typique décomposé qui affiche les attributs spécifiques d'un élément racine :

<Page

Élément objet d'ouverture de l'élément racine

xmlns="https://schemas.microsoft.com/winfx/2006/xaml/presentation"

Espace de noms XAML (WPF) par défaut

xmlns:x="https://schemas.microsoft.com/winfx/2006/xaml"

Espace de noms XAML de langage XAML

x:Class="ExampleNamespace.ExampleCode"

Déclaration de classe partielle qui connecte la balise à un code-behind quelconque défini pour la classe partielle

>

Fin d'un élément objet pour la racine. L'objet n'est pas encore fermé parce que l'élément contient des éléments enfants

Utilisations facultatives et non recommandées de XAML

Les sections suivantes décrivent des utilisations XAML techniquement prises en charge par les processeurs XAML, mais elles produisent des problèmes de commentaires ou d'esthétisme qui interfèrent avec les fichiers XAML qui restent explicites lorsque vous développez des applications qui contiennent des sources XAML.

Utilisations facultatives des éléments de propriété

Les utilisations facultatives des éléments de propriété incluent d'écrire explicitement les propriétés de contenu d'élément que le processeur XAML considère comme implicites. Par exemple, lorsque vous déclarez le contenu d'un Menu, vous pouvez choisir de déclarer explicitement la collection Items du Menu en tant que balise d'élément de propriété <Menu.Items> et de placer chaque MenuItem dans <Menu.Items>, plutôt que d'utiliser le comportement du processeur XAML implicite qui induit que tous les éléments enfants d'un Menu doivent être un MenuItem et soient placés dans la collection Items. Les utilisations facultatives peuvent parfois aider à clarifier visuellement la structure des objets telle qu'elle est représentée dans la balise. Ou bien une utilisation explicite d'une propriété d'élément peut parfois éviter un balisage techniquement fonctionnel mais visuellement confus, par exemple les extensions de balisage imbriquées dans une valeur d'attribut.

Attributs TypeName.memberName complètement qualifiés

typeName. Le format memberName pour un attribut fonctionne de manière plus universelle que le simple cas d'événement routé. Mais dans d'autres situations, cette forme est superflue et doit être évitée, au moins pour des raisons de style de balisage et de lisibilité. Dans l'exemple suivant, chacune des trois références à l'attribut Background est complètement équivalente :

<Button Background="Blue">Background</Button>
<Button Button.Background="Blue">Button.Background</Button>
<Button Control.Background="Blue">Control.Background</Button>

Button.Background fonctionne car la recherche qualifiée de cette propriété sur Button a réussi (Background a été hérité du Contrôle) et Button est la classe de l'élément objet ou une classe de base. Control.Background fonctionne parce que la classe Control définit réellement Background et que Control est une classe de base Button.

Toutefois, l'exemple de format typeName.memberName suivant ne fonctionne pas et, par conséquent, est accompagné de commentaires :

<!--<Button Label.Background="Blue">Does not work</Button> -->

Label est une autre classe dérivée de Control, et, si vous aviez spécifié Label.Background dans un élément objet Label, cette utilisation aurait fonctionné. Toutefois, du fait que Label n'est pas la classe ou la classe de base de Button, le comportement du processeur XAML spécifié consiste à traiter Label.Background comme une propriété jointe. Label.Background n'est pas une propriété jointe disponible, et cette utilisation échoue.

Propriété d'éléments baseTypeName.memberName

De la même manière que le format typeName.memberName fonctionne pour la syntaxe d'attribut, la syntaxe baseTypeName.memberName fonctionne pour la syntaxe des éléments de propriété. Par exemple, la syntaxe suivante fonctionne comme suit :

<Button>Control.Background PE
  <Control.Background>
    <LinearGradientBrush StartPoint="0,0" EndPoint="1,1">
      <GradientStop Color="Yellow" Offset="0.0" />
      <GradientStop Color="LimeGreen" Offset="1.0" />
    </LinearGradientBrush>
    </Control.Background>
</Button>

Ici, l'élément de propriété a été donné comme Control.Background bien que l'élément de propriété soit contenu dans Button.

Toutefois, comme le format typeName.memberName pour les attributs, le style baseTypeName.memberName ne convient pas pour le balisage et il convient de l'éviter pour des raisons de style.

Voir aussi

Concepts

Vue d'ensemble du langage XAML (WPF)

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

TypeConverters et XAML

XAML et classes personnalisées pour WPF

Autres ressources

Fonctionnalités de langage pour les espaces de noms XAML (x:)

Extensions XAML WPF