Partager via


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 utilisés fréquemment dans le reste de cette documentation, à la fois pour la documentation WPF spécifiquement et pour les autres frameworks qui utilisent XAML ou les concepts XAML de base activés par la prise en charge du langage XAML au niveau System.Xaml. Cette rubrique s’étend sur la terminologie de base introduite dans la rubrique XAML dans WPF.

Spécification du langage XAML

La terminologie de syntaxe XAML définie ici est également définie ou référencée dans la spécification du langage XAML. XAML est un langage basé sur XML et suit ou développe des règles structurelles XML. Une partie de la terminologie est partagée ou est basée sur la terminologie couramment utilisée lors de la description du langage XML ou du modèle objet de document XML.

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

XAML et CLR

XAML est un langage de balisage. Le Common Language Runtime (CLR), tel qu’il est implicite par son nom, active l’exécution du runtime. XAML n’est pas lui-même l’un des langages courants qui sont directement consommés par le runtime CLR. Au lieu de cela, vous pouvez considérer XAML comme prenant en charge son propre système de type. Le système d’analyse XAML particulier utilisé par WPF est basé sur le 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 code XAML pour WPF est analysé. Pour cette raison, le reste de la discussion de la syntaxe dans ce document inclut des références au système de type CLR, même si les discussions de syntaxe équivalentes dans la spécification du langage XAML ne le font pas. (Selon le niveau de spécification du langage XAML, les types XAML peuvent être mappés à n’importe quel autre système de type, qui n’a pas besoin du CLR, mais qui nécessiterait la création et l’utilisation d’un autre analyseur XAML.)

Membres des types et de l’héritage de classe

Les propriétés et les événements tels qu’ils apparaissent en tant que membres XAML d’un type WPF sont souvent hérités des types de base. Par exemple, considérez cet exemple : <Button Background="Blue" .../>. La propriété Background n’est pas une propriété déclarée immédiatement sur la classe Button, si vous deviez examiner la définition de classe, les résultats de réflexion ou la documentation. Au lieu de cela, Background est héritée de la classe de base Control.

Le comportement d’héritage de classe des éléments XAML WPF est un écart significatif de l’interprétation appliquée par le schéma du balisage XML. L’héritage de classes peut devenir complexe, en particulier lorsque les classes de base intermédiaires sont abstraites ou lorsque des interfaces sont impliquées. C’est une raison pour laquelle l’ensemble d’éléments XAML et leurs attributs autorisés est difficile à représenter avec précision et complètement à l’aide des types de schémas généralement utilisés pour la programmation XML, comme le format DTD ou XSD. Une autre raison est que les fonctionnalités d’extensibilité et de mappage de type du langage XAML lui-même empêchent toute représentation fixe des types et membres autorisés.

Syntaxe de l’élément Objet

La syntaxe de l'élément objet est la syntaxe de balisage XAML qui instancie une classe ou une structure CLR en déclarant un élément XML. Cette syntaxe ressemble à la syntaxe d’élément d’autres langages de balisage tels que HTML. La syntaxe de l’élément objet commence par un crochet à angle gauche (<), suivi immédiatement par le nom de type de la classe ou de la structure instanciée. Zéro ou plusieurs espaces peuvent suivre le nom du type, et zéro ou plusieurs attributs peuvent également être déclarés sur l’élément objet, avec un ou plusieurs espaces séparant chaque paire nom_valeur de chaque attribut. Enfin, l’un des éléments suivants doit être vrai :

  • L’élément et la balise doivent être fermés par une barre oblique (/) suivie immédiatement d’un crochet à angle droit (>).

  • La balise ouvrante doit être terminée par un crochet à angle droit (>). D’autres éléments d’objet, éléments de propriété ou texte interne peuvent suivre la balise d’ouverture. Exactement ce que le contenu peut contenir ici est généralement limité par le modèle objet de l’élément. La balise de fermeture équivalente pour l’élément objet doit également exister, dans une imbrication et un équilibre appropriés avec d’autres paires de balises ouvrantes et fermantes.

XAML tel que mis en œuvre par .NET a un ensemble de règles qui mappent des éléments d'objet en types, des attributs en propriétés ou événements, et les espaces de noms XAML en espaces de noms CLR ainsi que l'assembly. Pour WPF et .NET, les éléments d’objet XAML sont mappés aux types .NET tels que définis 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.

Par exemple, l’exemple suivant est la syntaxe de l’élément objet qui instancie une nouvelle instance de la classe Button, et spécifie également un attribut Name et une valeur pour cet attribut :

<Button Name="CheckoutButton"/>

L’exemple suivant est la syntaxe d’élément objet qui inclut également la syntaxe de propriété de contenu XAML. Le texte interne sera utilisé pour définir la propriété de contenu XAML TextBoxText.

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

Modèles de contenu

Une classe peut prendre en charge une utilisation en tant qu’élément d’objet XAML en termes de syntaxe, mais cet élément fonctionne correctement dans une application ou une page lorsqu’il est placé dans une position attendue d’un modèle de contenu global ou d’une arborescence d’éléments. Par exemple, une MenuItem doit généralement être placée en tant qu’enfant d’une classe dérivée MenuBase telle que Menu. Les modèles de contenu pour des éléments spécifiques sont documentés dans le cadre des remarques sur les pages de classes pour les contrôles et d’autres classes WPF qui peuvent être utilisées en tant qu’éléments XAML.

Propriétés des éléments d’objet

Les propriétés en XAML sont définies par diverses syntaxes possibles. Quelle syntaxe peut être utilisée pour une propriété particulière varie en fonction des caractéristiques système de type sous-jacentes de la propriété que vous définissez.

En définissant des valeurs de propriétés, vous ajoutez des caractéristiques ou des caractéristiques à des objets tels qu’ils existent dans le graphique d’objet d’exécution. L’état initial de l’objet créé à partir d’un élément objet est basé sur le comportement du constructeur sans paramètre. En règle générale, votre application utilise quelque chose d’autre qu’une instance complètement 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 d’objet existant. Le nom de l’attribut doit correspondre au nom de membre CLR de la propriété de la classe qui sous-tend l’élément objet concerné. Le nom de l’attribut est suivi d’un opérateur d’affectation (=). La valeur de l’attribut doit être une chaîne placée entre guillemets.

Note

Vous pouvez utiliser des guillemets alternés pour placer un guillemet littéral dans un attribut. Par exemple, vous pouvez utiliser des guillemets simples comme moyen de déclarer une chaîne qui contient un caractère de guillemet double dans celui-ci. Que vous utilisiez des guillemets simples ou doubles, vous devez utiliser une paire correspondante pour ouvrir et fermer la chaîne de valeur d’attribut. Il existe également des séquences d’échappement ou d’autres techniques disponibles pour contourner les restrictions de caractères imposées par une syntaxe XAML particulière. Consultez entités de caractères XML etXAML.

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

Pour les événements XAML WPF, l’événement référencé en tant que nom d’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 conteneur.

Traitement des valeurs d’attribut

La valeur de chaîne contenue dans les guillemets 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 remplie par l’un des éléments suivants, à l’aide de cet ordre de traitement :

  1. Si le processeur XAML rencontre une accolade, ou un élément d'objet dérivé de MarkupExtension, l’extension de balisage référencée est d'abord évaluée au lieu de traiter la valeur comme une chaîne, et l’objet retourné par l’extension de balisage est utilisé comme valeur. Dans de nombreux cas, l’objet retourné par une extension de balisage sera une référence à un objet existant, ou une expression qui reporte l’évaluation jusqu’au moment de l’exécution, et n’est pas un objet nouvellement instancié.

  2. Si la propriété est déclarée avec un TypeConverterattributé ou si le type valeur de cette propriété est déclaré avec un TypeConverterattribué, la valeur de chaîne de l’attribut est soumise au convertisseur de type comme entrée de conversion et le convertisseur retourne une nouvelle instance d’objet.

  3. S'il n'y a pas de TypeConverter, une tentative de conversion directe vers le type de propriété est effectuée. Ce niveau final est une conversion directe à la valeur native de l’analyseur entre les types primitifs du langage XAML, ou une vérification des noms des 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 d’une des constantes nommées de l’énumération.

Pour les valeurs d’énumération nonflag, le comportement natif consiste à traiter la chaîne d’une valeur d’attribut et à la résoudre en une des valeurs d’énumération. Vous ne spécifiez pas l’énumération au format Énumération.valeur, comme dans le code. Au lieu de cela, vous spécifiez uniquement Valeur, et Énumération est déduite du type de la propriété que vous définissez. Si vous spécifiez un attribut sous la forme Énumération.Valeur, il ne se résoudra pas correctement.

Pour les énumérations au niveau des indicateurs, le comportement est basé sur la méthode Enum.Parse. Vous pouvez spécifier plusieurs valeurs pour une énumération au niveau de l’indicateur en séparant chaque valeur par une virgule. Toutefois, vous ne pouvez pas combiner les valeurs d’énumération qui ne sont pas flagwise. Par exemple, vous ne pouvez pas utiliser la syntaxe de virgule pour tenter de créer un Trigger qui agit sur plusieurs conditions d’une énumération nonflag :

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

Les énumérations avec indicateur qui prennent en charge les attributs définis en XAML sont rares dans WPF. Toutefois, une telle énumération est StyleSimulations. Vous pouvez, par exemple, utiliser la syntaxe d’attribut délimité 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é où plusieurs valeurs d’énumération peuvent être spécifiées. Toutefois, cette propriété est un cas particulier, car l’énumération ModifierKeys prend en charge son propre convertisseur de type. Le convertisseur de type pour les modificateurs utilise un signe plus (+) comme 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, comme « Ctrl+Alt ».

Propriétés et références de nom de membre d’événement

Lorsque vous spécifiez un attribut, vous pouvez référencer n’importe quelle propriété ou événement qui existe en tant que membre du type CLR que vous avez instancié pour l’élément objet conteneur.

Vous pouvez également référencer une propriété jointe ou un événement attaché, indépendamment de l’élément objet conteneur. (Les propriétés jointes sont abordées dans une section à venir.)

Vous pouvez également nommer n’importe quel événement dans n'importe quel objet accessible via l’espace de noms par défaut en utilisant un typeName.événement nom partiellement qualifié ; cette syntaxe permet d'attacher des gestionnaires pour les événements routés où le gestionnaire est destiné à gérer le routage des événements à partir d'éléments enfants, mais l’élément parent n’a pas cet événement dans sa table membres. Cette syntaxe ressemble à une syntaxe d’événement jointe, mais l’événement ici n’est pas un vrai événement attaché. Au lieu de cela, vous référencez 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 parfois fournis comme valeur d’un attribut, plutôt que le nom de l’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 des noms de propriétés fournis en tant que valeur d’attribut sont différentes et sont régies par le type de la propriété en cours de définition ou par les comportements des sous-systèmes WPF particuliers. Pour plus d’informations, consultez Stylisation et Modélisation.

Une autre utilisation pour les noms de propriétés est lorsqu’une valeur d’attribut décrit une relation propriété-propriété. Cette fonctionnalité est utilisée pour la liaison de données et pour les cibles storyboard, et 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 XAML Syntax.

Syntaxe de l’élément Property

Syntaxe de l'élément Property diverge légèrement 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 affecter d’autres éléments d’objet à la valeur d’une propriété. Cette fonctionnalité est activée par la syntaxe de l’élément de propriété. Au lieu que la propriété soit spécifiée en tant qu'attribut dans la balise d'élément, elle est spécifiée à l'aide d'une balise d'élément ouvrante sous la forme elementTypeName.propertyName, la valeur de la propriété est spécifiée à l'intérieur, puis l'élément de propriété est fermé.

Plus précisément, la syntaxe commence par un crochet à angle gauche (<), suivie immédiatement par le nom de type de la classe ou de la structure dans laquelle la syntaxe de l’élément de propriété est contenue. Ceci est suivi immédiatement par un point unique (.), puis par le nom d’une propriété, puis par un crochet à angle 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 à affecter à la propriété est contenue dans l’élément de propriété. En règle générale, la valeur est donnée en tant qu’un ou plusieurs éléments d’objet, car la spécification d’objets en tant que valeurs est le scénario dans lequel la syntaxe de l’élément de propriété est destinée à s’adresser. Enfin, une balise de fermeture équivalente spécifiant la même combinaison elementTypeName.propertyName doit être fournie, dans une imbrication et un équilibre approprié avec d'autres balises d'élément.

Par exemple, voici la syntaxe de l’élément de propriété pour 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 d’un élément de propriété peut également être donnée en tant que texte interne, dans les cas où le type de propriété spécifié est un type de valeur primitif, tel que String, ou une énumération où un nom est spécifié. Ces deux utilisations sont quelque peu rares, car chacun de ces cas peut également utiliser une syntaxe d’attribut plus simple. Un scénario de remplissage d’un élément de propriété avec une chaîne concerne les propriétés qui ne sont pas la propriété de contenu XAML, mais qui sont toujours utilisées pour la représentation du texte de l’interface utilisateur, et des éléments d’espace blanc particuliers tels que les flux de lignes sont nécessaires pour apparaître dans ce texte d’interface utilisateur. La syntaxe d’attribut ne peut pas conserver les flux de lignes, mais la syntaxe de l’élément de propriété peut, tant que la conservation significative de l’espace blanc est active (pour plus d’informations, consultez traitement de l’espace blanc en XAML). Un autre scénario est afin que la directive x:Uid puisse être appliquée à l'élément de propriété, afin de marquer cette valeur comme une valeur qui devrait être localisée dans le fichier BAML de 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 pour définir une propriété et n’est pas un élément qui a une instance ou un objet qui le sauvegarde. (Pour plus d’informations sur le concept d’arborescence logique, consultez Arborescences dans WPF.)

Pour les propriétés où la syntaxe des attributs et des éléments de propriété sont prises en charge, les deux syntaxes ont généralement le même résultat, bien que les subtilités telles que la gestion des espaces blancs peuvent varier légèrement entre les syntaxes.

Syntaxe de collection

La spécification XAML nécessite des implémentations de processeur XAML pour identifier les propriétés où le type de valeur est une collection. L’implémentation générale du processeur XAML dans .NET est basée sur le code managé et le CLR, et elle identifie les types de collection via 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 d’objet. Au lieu de cela, les éléments destinés à devenir les éléments de la collection sont spécifiés comme un ou plusieurs éléments enfants de l’élément de propriété. Chaque élément de ce type est converti en objet pendant le chargement et ajouté à la collection en appelant la méthode Add de la collection implicite. Par exemple, la propriété Triggers de Style utilise le type de collection spécialisé TriggerCollection, qui implémente IList. Il n’est pas nécessaire d’instancier un élément d’objet TriggerCollection dans le balisage. Au lieu de cela, vous spécifiez un ou plusieurs éléments Trigger en tant qu’éléments dans l’élément de propriété Style.Triggers, où Trigger (ou une classe dérivée) est le type attendu comme type d’élément pour le TriggerCollectionfortement 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, qui est abordée dans la section suivante de cette rubrique.

Un élément de collection implicite crée un membre dans la représentation d’arborescence logique, même s’il n’apparaît pas dans le balisage en tant qu’élément. En règle générale, le constructeur du type parent effectue l’instanciation de la collection qui est l’une de ses propriétés, et la collection initialement vide fait partie de l’arborescence d’objets.

Note

Les interfaces de liste générique et de dictionnaire (IList<T> et IDictionary<TKey,TValue>) ne sont pas prises en charge pour la détection de regroupement. Toutefois, vous pouvez utiliser la classe List<T> comme classe de base, car elle implémente IList directement, ou Dictionary<TKey,TValue> en tant que classe de base, car elle implémente IDictionary directement.

Dans les pages de référence .NET pour les types de collection, cette syntaxe avec l’omission délibérée de l’élément objet d’une collection est parfois noté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 vraiment un élément qui est un ou les deux cas 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 seront abordées dans une section à venir). En d’autres termes, la relation des éléments parents et des éléments enfants dans une page de balisage est vraiment un objet unique situé à la racine, et chaque élément d’objet sous la racine est soit une instance unique qui fournit une valeur de propriété du parent, soit l’un des éléments d’une collection qui est elle-même une valeur de propriété de type collection du parent. Ce concept à racine unique est courant avec XML et est fréquemment renforcé dans le comportement des API qui chargent du code XAML comme Load.

L’exemple suivant est une syntaxe avec l’élément objet d’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 explicitement la collection. Par exemple, la tentative de déclarer TriggerCollection explicitement dans l’exemple Triggers précédemment indiqué échouerait. La déclaration explicite de la collection nécessite que la classe de collection prend en charge un constructeur sans paramètre et TriggerCollection n’a pas de constructeur sans paramètre.

Propriétés de contenu XAML

La syntaxe de contenu XAML est une syntaxe activée uniquement sur les classes qui spécifient l'ContentPropertyAttribute dans le cadre de leur déclaration de classe. La ContentPropertyAttribute fait référence au nom de propriété qui est la propriété de contenu de ce type d’élément (y compris les classes dérivées). Lorsqu’il est traité par un processeur XAML, tous les éléments enfants ou texte interne trouvés entre les balises d’ouverture et de fermeture de l’élément objet sont attribués comme valeur de la propriété de contenu XAML pour 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 généralement pas affichée dans les sections de syntaxe XAML de la référence .NET. La technique explicite/détaillée a une valeur occasionnelle pour la clarté du balisage ou comme une question de style de balisage, mais généralement l’intention d’une propriété de contenu est de rationaliser le balisage afin que les éléments qui sont intuitivement liés en tant que parent-enfant puissent être imbriqués directement. Les balises d’élément de propriété pour d’autres propriétés d’un élément ne sont pas affectées en tant que « contenu » conformément à une définition de langage XAML stricte ; ils sont traités précédemment dans l’ordre de traitement de l’analyseur XAML et ne sont pas considérés comme du « contenu ».

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

La valeur d’une propriété de contenu XAML doit être donnée entièrement avant ou entièrement après tout autre élément de propriété sur cet élément d’objet. Cela est vrai si la valeur d’une propriété de contenu XAML est spécifiée en tant que chaîne ou en tant qu’un ou plusieurs objets. Par exemple, le balisage suivant n’analyse pas :

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

Cela est illégal essentiellement parce que si cette syntaxe a été rendue explicite à l’aide de la syntaxe d’élément de propriété pour la propriété de contenu, la propriété de contenu est 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 similaire d'illégalité est si la propriété de contenu constitue une collection et que les éléments fils sont mélangés avec des éléments de propriété :

<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 plus d’un seul élément objet en tant que contenu, le type de la propriété de contenu doit être spécifiquement un type de collection. Comme pour la syntaxe des éléments de propriété pour les types de collection, un processeur XAML doit identifier les types qui sont des types de collection. Si un élément a une propriété de contenu XAML et que le type de la propriété de contenu XAML est une collection, le type de collection implicite n’a 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 le balisage peut désormais comporter plusieurs éléments enfants assignés comme contenu. Voici la syntaxe de contenu d’une classe dérivée Panel. Toutes les classes dérivées Panel établissent la propriété de contenu XAML à Children, ce qui nécessite une valeur de type UIElementCollection.

<Page
  xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
  xmlns:x="http://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 de l'UIElementCollection n’est requis dans le balisage. Il s’agit d’une fonctionnalité de conception de XAML afin que les éléments récursifs qui définissent une interface utilisateur soient représentés de manière plus intuitive sous la forme d’une arborescence d’éléments imbriqués avec des relations d’éléments parent-enfant immédiats, sans affecter les balises d’éléments de propriété ou les objets de collection. En fait, UIElementCollection ne peut pas être spécifié explicitement dans le balisage en tant qu’élément d’objet, par conception. Étant donné que son seul usage prévu est une collection implicite, UIElementCollection n’expose pas de constructeur sans paramètre public et ne peut donc pas être instancié en tant qu’élément objet.

Mélange d’éléments de propriété et d’éléments d’objet dans un objet avec une propriété de contenu

La spécification XAML déclare qu’un processeur XAML peut imposer que les éléments d’objet utilisés pour remplir la propriété de contenu XAML au sein d’un élément objet doivent être contigus et ne doivent pas être mélangés. Cette restriction contre le mélange d’éléments de propriété et de contenu est appliquée par les processeurs XAML WPF.

Vous pouvez avoir un élément d’objet enfant comme premier balisage immédiat au sein d’un élément d’objet. Vous pouvez ensuite introduire des éléments de propriété. Vous pouvez également spécifier un ou plusieurs éléments de propriété, puis le contenu, puis d’autres éléments de propriété. Toutefois, une fois qu’un élément de propriété suit le contenu, vous ne pouvez pas introduire de contenu supplémentaire, mais vous ne pouvez ajouter que des éléments de propriété.

Cette exigence d’ordre des éléments de contenu /propriété ne s’applique pas au texte interne utilisé comme contenu. Toutefois, il s’agit toujours d’un bon style de balisage pour conserver le texte interne contigu, car un espace blanc significatif sera difficile à détecter visuellement dans le balisage si les éléments de propriété sont entrelacés avec du 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 classiques, l’espace de noms XAML par défaut est spécifié comme espace de noms WPF. Vous pouvez spécifier des espaces de noms XAML autres que l’espace de noms XAML par défaut et utiliser toujours une syntaxe similaire. Toutefois, où qu’une classe soit nommée qui n’est pas accessible dans l’espace de noms XAML par défaut, ce nom de classe doit être précédé du préfixe de l’espace de noms XAML tel qu’il est mappé à l’espace de noms CLR correspondant. Par exemple, <custom:Example/> est une syntaxe d’élément objet pour instancier une instance de la classe Example, où l’espace de noms CLR contenant cette classe (et éventuellement les informations de l'assembly externe qui contiennent des types de support) avait é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 correspondance des espaces de noms pour WPF XAML.

Extensions de balisage

XAML définit une entité de programmation d'extension de balisage qui permet une échappatoire à la gestion normale du processeur XAML des valeurs d'attributs de chaîne ou d'éléments d'objet, et reporte le traitement à une classe de support. Le caractère qui identifie une extension de balisage pour un processeur XAML lors de l'usage de la syntaxe d’attribut est l’accolade ouvrante ({), suivi de tout caractère autre qu'une accolade fermante (}). La première chaîne suivant l’accolade ouvrante doit faire référence à la classe qui fournit le comportement d’extension particulier, et la référence peut omettre la sous-chaîne « Extension » si celle-ci fait partie du véritable nom de la classe. Par la suite, un espace unique peut apparaître, puis chaque caractère suivant est pris en compte par l’implémentation de l’extension, jusqu'à ce que l'accolade fermante soit rencontrée.

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 référencer 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 effectuée en spécifiant l’extension de balisage {Binding} à la place de la valeur qu’une propriété particulière prend généralement. La plupart des extensions de balisage WPF activent une syntaxe d’attribut pour les propriétés où une syntaxe d’attribut ne serait pas possible. 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 définis comme une ressource dans un ResourceDictionary, puis référencés via l’une des deux extensions de balisage WPF qui demandent une ressource. L’extension de balisage reporte l’évaluation de la valeur de 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>

Ici, StaticResource identifie la classe StaticResourceExtension fournissant l’implémentation de l’extension de balisage. La chaîne suivante MyStyle est utilisée comme entrée pour le constructeur StaticResourceExtension non par défaut, où le paramètre tel qu’il est extrait de la chaîne d’extension déclare le ResourceKeydemandé. MyStyle devrait être la valeur x :Key d’une Style définie comme une ressource. L'extension de balisage StaticResource est utilisée pour fournir la valeur de propriété Style en utilisant la recherche statique de ressources au moment du chargement.

Pour plus d'informations sur les extensions de balisage, consultez Markup Extensions et WPF XAML. Pour obtenir une référence des extensions de balisage et d’autres fonctionnalités de programmation XAML activées dans l’implémentation de XAML .NET, consultez Fonctionnalités du langage de l’espace de noms XAML (x:). Pour connaître 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 introduit en XAML dans lequel les propriétés peuvent être détenues 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 scénario principal pour lequel les propriétés jointes sont destinées 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 jointes peuvent être utilisées par les parents pour transmettre des informations aux éléments enfants. Pour plus d’informations sur l’objectif des propriétés jointes et sur la création de vos propres propriétés jointes, consultez Vue d’ensemble des propriétés jointes.

Les propriétés jointes utilisent une syntaxe qui ressemble superficiellement à la syntaxe de l’élément de propriété, dans laquelle vous spécifiez également un typeName . combinaisonpropertyName. Il existe deux différences importantes :

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

  • Vous pouvez également utiliser la syntaxe d’élément de propriété pour les propriétés jointes. Toutefois, pour la syntaxe d’élément de propriété classique, l'typeName que vous spécifiez est l’élément objet qui contient l’élément de propriété. Si vous faites référence à une propriété jointe, la typeName est la classe qui définit la propriété jointe, et non l’élément objet conteneur.

Événements joints

Les événements attachés sont un autre concept de programmation introduit en XAML, où les événements peuvent être définis par un type spécifique, mais les gestionnaires peuvent être attachés sur n’importe quel élément objet. Dans l’implémentation WOF, souvent le type qui définit un événement attaché est un type statique qui définit un service, et parfois ces événements attachés sont exposés par un alias d’événement routé dans les types qui exposent le service. Les gestionnaires pour les événements attachés sont spécifiés par le biais de la syntaxe d’attribut. Comme pour les événements attachés, la syntaxe d’attribut est étendue pour les événements attachés afin d’autoriser une utilisation de typeName.eventName, où typeName est la classe qui fournit des accesseurs de gestionnaire d’événements Add et Remove pour l’infrastructure des événements attachés, et eventName est le nom de l’événement.

Anatomie d’un élément racine XAML

Le tableau suivant montre un élément racine XAML classique décomposé, montrant les attributs spécifiques d’un élément racine :

Attribut Description
<Page Ouverture de l’élément objet de l’élément racine
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" Espace de noms XAML par défaut (WPF)
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" Espace de noms XAML du langage XAML
x:Class="ExampleNamespace.ExampleCode" Déclaration de classe partielle qui connecte le balisage à n’importe quel code-behind défini pour la classe partielle
> Fin de l’élément objet pour la racine. L’objet n’est pas encore fermé, car l’élément contient des éléments enfants

Utilisations XAML facultatives et non recommandées

Les sections suivantes décrivent les utilisations du XAML qui sont techniquement prises en charge par les processeurs XAML, mais qui produisent de la prolixité ou d'autres problèmes esthétiques qui interfèrent avec les fichiers XAML et qui demeurent lisibles par les humains lorsque vous développez des applications contenant des fichiers XAML.

Utilisations de l’élément Optional Property

Les utilisations facultatives des éléments de propriété incluent l’écriture explicite des propriétés de contenu d’élément que le processeur XAML considère implicites. Par exemple, lorsque vous déclarez le contenu d’un Menu, vous pouvez choisir de déclarer explicitement la collection Items du Menu comme balise d’élément de propriété <Menu.Items>, et placer chaque MenuItem dans <Menu.Items>, au lieu d’utiliser le comportement implicite du processeur XAML que tous les éléments enfants d’un Menu doivent être un MenuItem et sont placés dans la collection Items. Parfois, les utilisations facultatives peuvent aider à clarifier visuellement la structure d’objet telle qu’elle est représentée dans le balisage. Ou parfois, une utilisation explicite de l’élément de propriété peut éviter les marques techniques fonctionnelles, mais visuellement déroutantes, telles que les extensions de balisage imbriquées dans une valeur d’attribut.

Attributs pleinement qualifiés par typeName.memberName

TypeName .memberName formulaire pour un attribut fonctionne réellement plus universellement que le cas d’événement routé. Mais dans d’autres situations où la forme est superflue, vous devez l’éviter, ne serait-ce que 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 réussit (Background a été héritée de Control) et Button est la classe de l’élément objet ou d’une classe de base. Control.Background fonctionne, car la classe Control définit réellement Background et Control est une classe de base Button.

Toutefois, le typeName suivant.'exemple de formulaire memberName ne fonctionne pas et s’affiche ainsi commenté :

<!--<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, étant donné que Label n’est pas la classe ou la classe de base de Button, le comportement de processeur XAML spécifié consiste ensuite à traiter Label.Background en tant que propriété jointe. Label.Background n’est pas une propriété jointe disponible et cette utilisation échoue.

Éléments de propriété baseTypeName.memberName

De manière analogue à la façon dont la syntaxe du type .pour le formulaire membre fonctionne pour la syntaxe d’attribut, la syntaxe du type de base .pour le membre fonctionne pour la syntaxe d’élément de propriété. Par exemple, la syntaxe suivante fonctionne :

<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 même si l’élément de propriété était contenu dans Button.

Mais tout comme typeName. Le formulairememberName pour les attributs, baseTypeName.memberName est un style médiocre dans le balisage, et vous devriez l'éviter.

Voir aussi