Vue d'ensemble du langage XAML

Mise à jour : novembre 2007

Cette rubrique décrit les fonctionnalités du langage XAML (Extensible Application Markup Language) et explique comment l'utiliser pour écrire des applications Windows Presentation Foundation (WPF). Elle décrit plus spécifiquement le langage XAML implémenté par Windows Presentation Foundation (WPF). XAML est en soi un concept de langage plus vaste que Windows Presentation Foundation (WPF).

Cette rubrique comprend les sections suivantes.

  • Langage déclaratif avec prise en charge du contrôle de flux
  • Éléments d'objet XAML
  • Définition de propriétés
  • Valeurs de référence et extensions de balisage
  • Valeurs d'attribut activées par TypeConverter
  • Types de collections et propriétés de collection XAML
  • Propriétés de contenu XAML
  • Cas et espace blanc en XAML
  • Informations complémentaires sur la syntaxe XAML
  • Éléments racine XAML et espaces de noms XML
  • Événements et code-behind XAML
  • x:Name
  • Propriétés et événements attachés
  • Classes de base et XAML
  • Sécurité XAML
  • Chargement de XAML à partir du code
  • Quoi d'autre ?
  • Rubriques connexes

Langage déclaratif avec prise en charge du contrôle de flux

Le XAML simplifie la création d'une interface utilisateur pour le modèle de programmation .NET Framework. Vous pouvez créer des éléments d'interface utilisateur visibles dans la balise XAML déclarative, puis séparer la définition de l'interface utilisateur de la logique au moment de l'exécution en utilisant des fichiers code-behind, joints à la balise par le biais de définitions de classe partielles. La possibilité de combiner code et balise en XAML est importante dans la mesure où le XML est déclaratif en soi et ne suggère pas vraiment de modèle pour le contrôle de flux. Un langage déclaratif basé sur XML est très intuitif pour créer des interfaces allant du prototype à la production, en particulier pour les personnes ayant une certaine expérience de la conception et des technologies du Web. Contrairement à la plupart des autres langages de balisage, le XAML représente directement l'instanciation des objets managés. Ce principe de conception générale permet de simplifier le code et d'octroyer un accès en débogage pour les objets créés en XAML.

Les fichiers XAML sont des fichiers XML qui portent généralement l'extension .xaml.

L'exemple XAML suivant montre que la balise nécessaire pour créer un bouton dans le cadre d'une interface utilisateur est peu importante. Le bouton créé a une présentation visuelle par défaut par le biais de styles de thème et des comportements par défaut par l'intermédiaire de sa conception de classe.

<StackPanel>
  <Button Content="Click Me"/>
</StackPanel>

Éléments d'objet XAML

Le XAML possède un jeu de règles qui mappent des éléments d'objet en classes ou structures, des attributs en propriétés ou événements, et des espaces de noms XML en espaces de noms CLR. Les éléments XAML sont mappés en types Microsoft .NET tels que définis dans des assemblys référencés, tandis que les attributs sont mappés en membres de ces types.

Deux éléments d'objet sont spécifiés dans l'exemple ci-dessus : <StackPanel> (avec une balise de fermeture), et <Button/> (qui comportait également plusieurs attributs ; les attributs seront examinés dans une prochaine section). Les chaînes StackPanel et Button sont toutes deux mappées en nom de classe qui est définie par WPF et fait partie des assemblys WPF. Lorsque vous spécifiez une balise d'élément d'objet, vous créez une instruction demandant au traitement XAML de créer une nouvelle instance de la classe nommée lorsque votre page XAML est chargée. Chaque instance est créée en appelant le constructeur par défaut de la classe ou structure sous-jacente et en stockant le résultat. Pour pouvoir être utilisée en tant qu'élément d'objet en XAML, la classe ou la structure doit exposer un constructeur public par défaut (sans paramètre).

Définition de propriétés

Les propriétés en XAML sont définies par le biais de la définition de propriétés sur un élément d'objet, à l'aide de diverses syntaxes. Les syntaxes utilisables pour une propriété donnée varient en fonction des caractéristiques de la propriété en question.

En définissant des valeurs de propriétés, vous ajoutez des fonctionnalités ou des caractéristiques aux éléments d'objet. L'état initial de l'instance d'objet sous-jacente d'un élément d'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

En XAML, les propriétés peuvent souvent être exprimées sous forme d'attributs. La syntaxe d'attribut est la syntaxe de définition de propriétés la plus simplifiée, en plus d'être la plus intuitive, ce qui devrait pousser les développeurs qui utilisaient des langages de balisage par le passé à la choisir. Par exemple, la balise suivante crée un bouton comportant du texte rouge et un arrière-plan bleu, de même que le texte affiché spécifié en tant que Content.

<Button Background="Blue" Foreground="Red" Content="This is a button"/>

Syntaxe d'élément de propriété

Il n'est parfois pas possible d'utiliser la syntaxe d'attribut avec certaines propriétés d'un élément d'objet, car l'objet ou les informations nécessaires pour définir la valeur de la propriété ne peuvent pas être exprimés de manière appropriée par une simple chaîne. Dans ces cas-là, une syntaxe différente, connue sous le nom de syntaxe d'élément de propriété, peut être utilisée. Cette syntaxe définit la propriété référencée de l'élément conteneur à l'aide du contenu de la balise. En général, le contenu est un objet du type que la propriété utilise comme valeur (l'instance définissant la valeur étant généralement spécifiée en tant qu'autre élément d'objet). La syntaxe d'élément de propriété est <NomType.Propriété>. Après avoir spécifié le contenu, vous devez fermer l'élément de propriété avec une balise de fermeture comme pour tout autre élément (à l'aide de la syntaxe </NomType.Propriété>). 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). Lorsqu'une syntaxe d'attribut peut être utilisée, son utilisation sera privilégiée dans la mesure où elle est plus pratique et permet d'avoir une balise plus compacte. Ce n'est toutefois qu'une question de style et non de limitation technique. L'exemple suivant illustre la définition des mêmes propriétés que dans l'exemple de syntaxe d'attribut ci-dessus, mais cette fois en utilisant la syntaxe d'élément de propriété pour l'ensemble des propriétés du Button.

<Button>
  <Button.Background>
    <SolidColorBrush Color="Blue"/>
  </Button.Background>
  <Button.Foreground>
    <SolidColorBrush Color="Red"/>
  </Button.Foreground>
  <Button.Content>
    This is a button
  </Button.Content>
</Button>

La syntaxe d'élément de propriété pour le XAML constitue une grande nouveauté par rapport à l'interprétation XML de base de la balise. Pour XML, <NomType.Propriété> représente un autre élément, qui n'a pas de relation nécessairement implicite à un parent TypeName en dehors du fait d'être un élément enfant. En XAML, <NomType.Property> implique directement que Property est une propriété de NomType, défini par le contenu de l'élément de propriété et ne sera jamais un élément portant un nom similaire, mais bien un élément discret qui, paradoxalement, s'avère avoir un point dans son nom.

Propriétés et héritage de classe

Les propriétés qui apparaissent comme des attributs XAML sur un élément WPF sont souvent héritées à partir de classes de base. Ainsi, dans l'exemple précédent, 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 la 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 WPFXAML est une autre nouveauté majeure par rapport à l'interprétation XML de base de la balise. L'héritage de classe (en particulier lorsque les classes de base intermédiaires sont abstraites) est 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. De plus, le « X » de XAML signifie « extensible » ; or l'extensibilité exclut l'exhaustivité de toute représentation donnée de « ce qu'est XAML pour WPF » (même si la conservation de définitions d'espaces de noms XML distinctes peut contribuer à résoudre ce problème, ce concept étant abordé dans une autre section).

Valeurs de référence et extensions de balisage

Les extensions de balisage sont un concept XAML. Dans la syntaxe d'attribut, les accolades ({ et }) indiquent l'utilisation d'une extension de balisage. Cette utilisation ordonne au traitement XAML de se soustraire au traitement général des valeurs d'attribut en tant que chaîne littérale ou valeur directement convertible en chaîne.

Lorsque des propriétés prennent la valeur d'un type référence, elles ont généralement besoin d'une syntaxe d'élément de propriété (laquelle crée toujours une instance) ou d'une référence d'objet par le biais d'une extension de balisage. Une utilisation d'extension de balisage est susceptible de retourner une instance existante et peut dès lors s'avérer plus flexible ou subir une moindre charge mémoire d'objet.

Lorsqu'une extension de balisage est utilisée pour fournir une valeur d'attribut, celle-ci doit être fournie à la place par la logique de la classe de stockage de l'extension de balisage appropriée. Les extensions de balisage les plus courantes utilisées dans la programmation d'applications WPF sont Binding, qui est utilisée pour les expressions de liaison de données, et les références de ressource StaticResource et DynamicResource. L'utilisation d'extensions de balisage vous permet d'utiliser la syntaxe d'attribut pour attribuer des valeurs de référence à une propriété, même si cette propriété ne prend pas en charge de syntaxe d'attribut pour l'instanciation directe de l'objet, ou d'autoriser un comportement spécifique déférant le comportement général de l'exigence en vertu de laquelle les propriétés XAML sont tenues de recevoir des valeurs provenant du type de la propriété.

Ainsi, dans l'exemple suivant, la valeur de la propriété Style est définie à l'aide de la syntaxe d'attribut. La propriété Style prend une instance de la classe Style, un type référence qui, par défaut, ne pouvait pas être spécifié dans une chaîne de syntaxe d'attribut. Mais dans ce cas, l'attribut référence une extension de balisage particulière, StaticResource. Lorsque cette extension de balisage est traitée, elle retourne une référence à un style qui a été instancié précédemment en tant que ressource indexée dans un dictionnaire de ressources.

<Page.Resources>
  <SolidColorBrush x:Key="MyBrush" Color="Gold"/>
  <Style TargetType="Border" x:Key="PageBackground">
    <Setter Property="Background" Value="Blue"/>
  </Style>


...


</Page.Resources>
<StackPanel>
  <Border Style="{StaticResource PageBackground}">


...


  </Border>
</StackPanel>

Les ressources ne sont qu'une des utilisations d'extension de balisage autorisées par WPF ou XAML. Pour obtenir une liste de référence des extensions de balisage, consultez Extensions XAML des espaces de noms WPF ou Fonctionnalités de langage pour les espaces de noms XAML (x:). Pour plus d'informations sur les extensions de balisage, consultez Extensions de balisage et XAML.

Valeurs d'attribut activées par TypeConverter

Dans la section Syntaxe d'attribut, il a été signalé que la valeur de l'attribut devait pouvoir être définie par une chaîne. La procédure native de base qui permet de convertir les chaînes en d'autres types d'objet ou valeurs primitives est fonction du type de String lui-même. Mais de nombreux types de WPF ou des membres de ces types étendent le comportement de traitement de base des attributs de chaîne, de sorte que des instances de types d'objets plus complexes puissent être spécifiées comme valeurs d'attribut via une chaîne. Au niveau du code, cette opération est effectuée en spécifiant un convertisseur de type CLR qui traite la valeur de l'attribut de chaîne. Le type de structure Thickness, généralement utilisé pour indiquer les dimensions d'une zone rectangulaire telle qu'une Margin, est un exemple de type doté d'une syntaxe d'attribut activée par typeconverter spéciale exposée pour toutes les propriétés adoptant ce type, afin de faciliter l'utilisation dans la balise XAML. L'exemple suivant utilise une syntaxe d'attribut activée par typeconverter pour attribuer une valeur à une Margin :

<Button Margin="10,20,10,30" Content="Click me"/>

L'exemple de syntaxe d'attribut ci-dessus équivaut à l'exemple suivant de syntaxe plus documentée, dans lequel la Margin est définie par le biais de la syntaxe d'élément de propriété qui contient un élément objet Thickness et où quatre propriétés de clé de Thickness sont définies comme attributs sur la nouvelle instance :

<Button Content="Click me">
  <Button.Margin>
    <Thickness Left="10" Top="20" Right="10" Bottom="30"/>
  </Button.Margin>
</Button>

Le choix de la syntaxe activée par typeconverter ou d'une syntaxe équivalente plus documentée est généralement fonction du style de codage souhaité. La syntaxe activée par typeconverter permet toutefois d'avoir des balises simplifiées. (Cependant, pour un nombre limité d'objets, le typeconverter est la seule manière d'affecter une propriété à ce type, car l'objet de type lui-même ne possède pas de constructeur par défaut. C'est le cas notamment de Cursor.)

Pour plus d'informations sur la prise en charge de la syntaxe d'attribut activée par typeconverter, consultez TypeConverters et XAML.

Types de collections et propriétés de collection XAML

Le XAML spécifie une fonctionnalité de langage en vertu de laquelle l'élément objet représentant un type de collection peut être délibérément omis de balise. Lorsqu'un processeur XAML gère une propriété qui prend un type de collection, une instance du type collection approprié est créée implicitement, même si l'élément objet de cette collection ne figure pas dans la balise. Dans les pages de référence Kit de développement logiciel (SDK) pour les types de collections, cette syntaxe avec omission délibérée de l'élément objet pour une collection est parfois appelée dans les sections de syntaxe XAML en tant que syntaxe de collection implicite.

La syntaxe de collection implicite est disponible pour les types qui implémentent IList ou IDictionary, ou pour les tableaux.

Vous avez déjà pu voir un exemple de syntaxe de collection implicite non appelée, dans l'exemple de ressources XAML :

<Page.Resources>
  <SolidColorBrush x:Key="MyBrush" Color="Gold"/>
  <Style TargetType="Border" x:Key="PageBackground">
    <Setter Property="Background" Value="Blue"/>
  </Style>


...


</Page.Resources>
<StackPanel>
  <Border Style="{StaticResource PageBackground}">


...


  </Border>
</StackPanel>

À l'exception de l'élément racine, chaque élément objet d'une page imbriquée en tant qu'élément enfant d'un autre élément est en fait un élément d'un 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 examiné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. Dans le cas de l'exemple des ressources, la propriété Resources utilise un objet de type ResourceDictionary. L'exemple suivant propose une syntaxe équivalente à l'élément objet pour le ResourceDictionary spécifié explicitement.

<Page.Resources>
  <ResourceDictionary>
      <SolidColorBrush x:Key="MyBrush" Color="Gold"/>
      <Style TargetType="Border" x:Key="PageBackground">
        <Setter Property="Background" Value="Blue"/>
      </Style>


...


  </ResourceDictionary>
</Page.Resources>
<StackPanel>
  <Border Style="{StaticResource PageBackground}">


...


    </Border>
  </StackPanel>
</Page>

La collection Resources est un exemple de propriété de collection présente sur de nombreux éléments de niveau d'infrastructure WPF courants. La définition de cette propriété en XAML requiert la syntaxe de propriété d'élément. Chaque élément objet englobé dans l'élément de propriété devient un élément de la collection (une implémentation IDictionary). Bien que le type de collection lui-même ait généralement une propriété ou un indexeur qui contient les éléments, cette propriété ne peut pas être spécifiée dans le balisage ; elle est totalement implicite. Pour le ResourceDictionary, cette propriété est l'indexeur Item.

Pour obtenir un exemple plus complet d'utilisation du dictionnaire de ressources, consultez Comment : définir et référencer une ressource.

Propriétés de contenu XAML

Le XAML spécifie une fonctionnalité de langage en vertu de laquelle toute classe pouvant être utilisée en tant qu'élément objet XAML peut désigner exactement une de ses propriétés en tant que propriété de contenu XAML pour les instances de la classe. Lorsqu'un processeur XAML gère un élément objet qui a une propriété de contenu XAML, tous les éléments enfants XML de cet élément objet sont traités comme s'ils étaient contenus dans une balise d'élément de propriété implicite représentant cette propriété de contenu. Dans votre balise, vous pouvez omettre la syntaxe d'élément de propriété pour la propriété de contenu XAML. Tous les éléments enfants que vous spécifiez dans la balise sont utilisés comme valeur de la propriété de contenu XAML.

Le tout premier exemple de cette rubrique vous montrait une propriété de contenu XAML qui n'était pas appelée.

<StackPanel>
  <Button Content="Click Me"/>
</StackPanel>

Dans ce cas-ci, Button est un élément enfant de StackPanel. Il s'agit d'une balise simplifiée et intuitive qui omet deux instructions pour deux raisons différentes.

  • Élément de propriété StackPanel.Children omis : StackPanel dérive de Panel. Panel définit Panel.Children comme étant sa propriété de contenu XAML. Toutes les classes dérivées de Panel ont par conséquent cette propriété de contenu XAML et l'élément de propriété pour Panel.Children peut être omis.

  • Élément objet UIElementCollection omis : La propriété Panel.Children prend le type UIElementCollection, qui implémente IList. Par conséquent, la balise de l'élément objet UIElementCollection peut être omise, en vertu des règles XAML applicables aux collections. Dans ce cas, UIElementCollection ne peut pas être réellement instancié en tant qu'élément objet. Vous n'avez même pas la possibilité de déclarer cet objet de collection de manière explicite car UIElementCollection n'expose pas de constructeur par défaut. Plusieurs autres types de collection WPF n'exposent pas non plus de constructeurs pour l'utilisation d'éléments objet, parce que le traitement de la syntaxe de collection XAML leur permet de continuer à travailler implicitement en XAML. C'est pourquoi l'élément objet UIElementCollection apparaît avec des commentaires dans l'exemple ; sans commentaire, l'exemple ne serait pas compilé.

<StackPanel>
  <StackPanel.Children>
    <!--<UIElementCollection>-->
    <Button>
      <Button.Content>
        Click Me
      </Button.Content>
    </Button>
    <!--</UIElementCollection>-->
  </StackPanel.Children>
</StackPanel>

Texte interne et propriétés de contenu XAML

L'exemple StackPanel / Button possède encore une autre variation.

<StackPanel>
  <Button>Click Me</Button>
</StackPanel>

Remarquez le changement au niveau de la spécification du texte affiché pour le Button. La propriété Content a été spécifiée dans la syntaxe d'attribut précédemment ; cette fois, la chaîne affichée est le texte interne dans un élément objet Button. Cette syntaxe fonctionne parce que Content est la propriété de contenu XAML de la Button classe de base ContentControl. La chaîne dans l'élément est évaluée en fonction du type de la propriété Content, qui est Object. Object n'essaie pas de convertir le type de chaîne, car la propriété Content prend la valeur de la chaîne littérale. Le contenu dans le Button aurait également pu être un Object unique. Des contrôles tels que Button définissent généralement la propriété de contenu XAML pour la classe de manière à ce que la propriété de contenu XAML puisse être utilisée pour le texte affiché et le texte de l'interface utilisateur, pour la composition de contrôle, ou les deux.

La possibilité de placer des chaînes dans l'élément en tant que contenu pour produire une balise similaire à d'autres langages de balisage courants est particulièrement importante pour le modèle de document dynamique (pour plus de détails, consultez Documents dans Windows Presentation Foundation) et pour la localisation (consultez Globalisation pour Windows Presentation Foundation).

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

La valeur d'une propriété de contenu XAML doit être passé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 si la valeur d'une propriété de contenu XAML est spécifiée en tant que chaîne ou sous la forme d'un ou plusieurs objets. Par exemple, la balise suivante ne compile 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 de propriété d'élément 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>

Modèles de contenu

Une classe peut prendre en charge une utilisation en tant qu'élément 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 total 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. Pour certains contrôles dont les modèles de contenu sont plus complexes, le modèle de contenu est documenté dans une rubrique conceptuelle distincte. Consultez Modèles de contenu.

Cas et espace blanc en XAML

Le XAML respecte la casse. Les éléments objet, les éléments de propriété et les noms d'attribut doivent être spécifiés à l'aide de la casse correcte en comparant le nom au type sous-jacent dans l'assembly ou à un membre d'un type. Les valeurs des attributs ne respectent pas toujours la casse. Le respect de la casse par les valeurs dépend du comportement du convertisseur de type associé à la propriété qui prend la valeur ou du type valeur de la propriété. Par exemple, les propriétés qui prennent le type Boolean peuvent prendre la valeur true ou True, qui sont équivalentes, mais uniquement parce que la conversion du type de chaîne par défaut pour Boolean accepte ces valeurs comme étant équivalentes.

Les processeurs et les sérialiseurs XAML ignorent ou suppriment tous les espaces blancs non significatifs et normalisent ceux qui sont significatifs. Ce comportement n'a généralement de conséquences que lorsque vous spécifiez des chaînes dans des propriétés de contenu XAML. En résumé, le XAML convertit les espaces, les sauts de ligne et les tabulations en espaces, puis conserve un seul espace à chacune des extrémités d'une chaîne contiguë. La gestion des espaces blancs XAML n'est pas couverte de manière exhaustive dans cette rubrique. Pour plus d'informations, consultez Traitement des espaces blancs en XAML.

Informations complémentaires sur la syntaxe XAML

La syntaxe de collection implicite et les propriétés de contenu XAML sont deux fonctionnalités du langage XAML qui autorisent l'omission de certaines balises déduites. Elles ont pour but de rendre les relations parent-enfant des éléments d'une page plus apparentes lors de la création ou de l'examen de la balise.

Pour plus d'informations sur la syntaxe d'attribut et la syntaxe d'élément de propriété, ainsi que sur les autres termes utilisés lors de la description de la syntaxe XAML dans la documentation Kit de développement logiciel (SDK), consultez Terminologie de la syntaxe XAML. La rubrique Terminologie de la syntaxe XAML constitue également un excellent point de départ idéal afin de déterminer les utilisations de XAML à activer lors de la création d'une classe personnalisée.

Éléments racine XAML et espaces de noms XML

Un fichier XAML ne peut contenir qu'un seul élément racine pour être à la fois un fichier valide et de forme correcte. En général, vous devez choisir un élément qui fait partie du modèle d'application (par exemple, Window ou Page pour une page, ResourceDictionary pour un dictionnaire externe ou Application pour la racine de la définition d'application). L'exemple suivant montre l'élément racine d'un fichier XAML type pour une page WPF, avec l'élément racine Page.

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


...


</Page>

L'élément racine contient également les attributs xmlns et xmlns:x. Ces attributs indiquent à un processeur XAML les espaces de noms XML qui contiennent les définitions des éléments qui seront référencés par le balisage. L'attribut xmlns indique spécifiquement l'espace de noms XML par défaut. Dans l'espace de noms XML par défaut, les éléments objet du balisage peuvent être spécifiés sans préfixe. Dans la plupart des scénarios d'application WPF et pour la quasi-totalité des exemples donnés dans les sections WPF du Kit de développement logiciel (SDK), l'espace de noms XML par défaut est mappé à l'espace de noms WPF (https://schemas.microsoft.com/winfx/2006/xaml/presentation). L'attribut xmlns:x indique un espace de noms XML supplémentaire, qui mappe l'espace de noms du langage XAML (https://schemas.microsoft.com/winfx/2006/xaml. Les composants de langage requis définis par la spécification XAML sont précédés du préfixe x: lorsqu'ils sont référencés dans la balise d'un fichier avec ce mappage. Cette utilisation de xmlns pour définir une portée pour l'utilisation et le mappage est cohérente avec la spécification XML 1.0. Notez que les attributs xmlns sont uniquement obligatoires sur l'élément racine de chaque page et sur la définition d'application lorsque celle-ci est fournie dans la balise. Les définitions de xmlns s'appliquent à tous les éléments enfants de la racine (ce comportement est lui aussi cohérent avec la spécification XML 1.0 pour xmlns). Les attributs xmlns sont également autorisés sur d'autres éléments situés sous la racine et s'appliquent à tous les éléments enfants de l'élément définissant. Cette utilisation est toutefois rare, car la définition ou la redéfinition fréquente d'espaces de noms XML peut donner lieu à un style de balisage XAML difficile à lire.

Les assemblys WPF sont connus pour contenir les types qui prennent en charge les mappages WPF à l'espace de noms XML par défaut, car la configuration est intégrée au fichier de génération de votre projet. Les assemblys sont également mappés dans les fichiers cibles. Par conséquent, le mappage de xmlns est la seule opération nécessaire pour référencer des éléments XAML provenant d'assemblys WPF. Dans le cas d'assemblys personnalisés ou d'assemblys en dehors de WPF, vous pouvez spécifier l'assembly qui fait partie du mappage xmlns. En règle générale, vous choisirez un préfixe différent, mais il est également possible de choisir un espace de noms XML différent comme valeur par défaut, puis de mapper WPF à un préfixe. Pour plus d'informations sur la relation entre les espaces de noms XML et les espaces de noms du code de stockage dans les assemblys, consultez Espaces de noms XAML et mappage d'espace de noms.

Le préfixe x:

Dans l'exemple d'élément racine ci-dessus, le préfixe x: était utilisé pour mapper l'espace de noms XML XAML (https://schemas.microsoft.com/winfx/2006/xaml). Ce préfixe x: est utilisé pour mapper l'espace de noms XML XAML dans les modèles de projets, dans des exemples et dans la documentation sur ce Kit de développement logiciel (SDK). L'espace de noms XML x: prefix/XAML contient plusieurs constructions de programmation que vous utiliserez très fréquemment dans votre XAML. Les constructions de programmation d'espaces de noms x: prefix/XAML que vous utiliserez le plus souvent sont répertoriées dans la liste suivante :

  • x:Key : définit une clé unique pour chacune des ressources d'un ResourceDictionary. x:Key représente environ 90 % des cas d'utilisation de x: que vous verrez dans la balise de votre application.

  • x:Class : spécifie l'espace de noms CLR et le nom de la classe qui fournit le code-behind pour une page XAML. Une telle classe est nécessaire pour prendre en charge le code-behind, raison pour laquelle vous verrez presque toujours le préfixe x: mappé, même s'il n'y a pas de ressources.

  • x:Name : spécifie un nom d'objet au moment de l'exécution pour l'instance qui existe dans le code au moment de l'exécution après qu'un élément objet a été traité. Vous utiliserez x:Name pour nommer des éléments lorsque la propriété Name de niveau d'infrastructure WPF équivalente n'est pas prise en charge. Cela peut arriver dans certains scénarios d'animation.

  • x:Static : active une référence de valeur qui reçoit une valeur statique qui, dans d'autres circonstances, n'est pas une propriété compatible XAML. 

  • x:Type : construit une référence Type en fonction d'un nom de type. Il est utilisé pour spécifier des attributs qui prennent Type, tels que Style.TargetType, même si, dans de nombreux cas, la propriété propose une conversion de chaîne en Type native qui fait que l'utilisation de x:Type est facultative.

Il existe d'autres constructions de programmation dans l'espace de noms x: prefix/XAML qui ne sont pas aussi courantes. Pour plus d'informations, consultez Fonctionnalités de langage pour les espaces de noms XAML (x:).

Événements et code-behind XAML

La plupart des applications WPF sont composées de balises et de code-behind. Dans un projet, le code XAML est écrit sous la forme d'un fichier .xaml et un langage CLR, tel que Microsoft Visual Basic .NET ou C#, est utilisé pour écrire un fichier code-behind. Lorsqu'un fichier XAML est compilé, l'emplacement du fichier code-behind XAML pour chaque page XAML est identifié en spécifiant un espace de noms et une classe en tant qu'attributs x:Class de l'élément racine de la page XAML.

Dans les exemples examinés jusqu'à présent, vous avez vu plusieurs boutons, mais aucun comportement logique ne leur a été associé jusqu'à présent. Au niveau de l'application, le mécanisme de base pour ajouter un comportement pour un élément objet consiste à utiliser un événement existant de l'élément classe et d'écrire un gestionnaire spécifique pour cet événement appelé lorsque cet événement est déclenché au moment de l'exécution. Le nom de l'évènement et le nom du gestionnaire à utiliser sont spécifiés dans la balise, tandis que le code qui implémente votre gestionnaire est défini dans le code-behind.

<Page 
  xmlns="https://schemas.microsoft.com/winfx/2006/xaml/presentation"
  xmlns:x="https://schemas.microsoft.com/winfx/2006/xaml"
  x:Class="MyNamespace.MyPageCode">
  <Button Click="ClickHandler" >Click Me!</Button>
</Page>
namespace MyNamespace
{
  public partial class MyPageCode
  {
    void ClickHandler(object sender, RoutedEventArgs e)
    {
      Button b = e.Source as Button;
      b.Background = Brushes.Red;
    }
  }
}

Notez que le fichier code-behind utilise l'espace de noms CLR MyNamespace et déclare MyPageCode en tant que classe partielle de cet espace de noms. Cela correspondant à la valeur d'attribut x:Class de MyNamespace.MyPageCode qui a été fournie dans la racine de la balise. Le compilateur crée automatiquement une classe partielle pour toute page XAML compilée, en dérivant une classe à partir du type d'élément racine. Lorsque vous fournissez un code-behind qui définit cette même classe partielle, le code résultant est combiné dans les mêmes espace de noms et classe de l'application compilée.

Pour plus d'informations sur les exigences associées à la programmation de code-behind, consultez la section « Exigences concernant le code-behind, le gestionnaire d'événements et les classes partielles » de Code-behind et XAML.

Si vous ne souhaitez pas créer de fichier code-behind distinct, vous pouvez également incorporer votre code dans un fichier XAML. Ce code incorporé est toutefois une technique moins flexible et qui présente des limitations substantielles. Pour plus d'informations, consultez Code-behind et XAML.

Syntaxe d'attribut d'événement

Lorsque vous spécifiez le comportement à travers des événements dans la balise, vous utilisez généralement une syntaxe d'attribut pour attacher des gestionnaires. L'élément objet dans lequel l'attribut d'événement est spécifié devient l'instance qui écoute l'événement et appelle le gestionnaire. Le nom de l'événement spécifique que vous souhaitez gérer est le nom d'attribut. La valeur d'attribut est le nom de la méthode du gestionnaire que vous définissez. Vous devez ensuite fournir l'implémentation de gestionnaire en code-behind, le gestionnaire reposant sur le délégué pour cet événement. L'écriture du gestionnaire en code-behind peut se faire dans un langage de programmation tel que Microsoft Visual Basic .NET ou C#.

Lors de son déclenchement, chaque événement WPF signale des données d'événement, auxquelles les gestionnaires d'événements peuvent accéder. Dans l'exemple précédent, le gestionnaire obtient la source d'événement signalée par le biais des données d'événement, puis définit des propriétés sur cette source.

Événements routés

Les événements routés sont une fonctionnalité d'événement particulière unique et fondamentale de WPF. Les événements routés permettent à un élément de gérer un événement déclenché par un autre élément, pour autant qu'ils soient connectés par le biais une relation d'arborescence d'éléments. Lorsque vous spécifiez la gestion des événements avec un attribut XAML, vous pouvez écouter et gérer l'événement routé sur n'importer quel élément, y compris les éléments qui ne répertorient pas cet événement particulier dans la table des membres de la classe. Pour ce faire, vous devez qualifier l'attribut de nom de l'évènement avec le nom de classe possédant. Par exemple, le StackPanel parent dans l'exemple StackPanel / Button en cours peut enregistrer un gestionnaire pour l'événement Click du bouton de l'élément enfant en spécifiant l'attribut Button.Click sur l'élément objet StackPanel, avec le nom de votre gestionnaire comme valeur d'attribut. Pour plus d'informations, consultez Vue d'ensemble des événements routés.

x:Name

Par défaut, l'instance d'objet créée lors du traitement d'un élément objet ne possède pas d'identificateur unique ni de référence d'objet inhérente que vous pourriez utiliser dans votre code. Si vous appelez un constructeur dans le code, vous utilisez presque toujours le résultat de constructeur pour attribuer une variable à l'instance construite, de manière à pouvoir référencer l'instance ultérieurement dans votre code. Pour fournir un accès standardisé à des objets créés à l'aide d'une définition de balise, XAML définit l'attribut x:Name. Vous pouvez définir la valeur de l'attribut x:Name sur n'importe quel élément objet. Dans votre code-behind, l'identificateur que vous choisissez équivaut à une variable d'instance qui fait référence à l'instance construite. Les éléments nommés fonctionnent à tous points de vue comme s'ils étaient des instances d'objet (le nom référence simplement cette instance) et votre code-behind peut référencer les éléments nommés pour gérer des interactions au moment de l'exécution dans l'application.

Les éléments XAML au niveau de l'infrastructure WPF héritent une propriété Name, qui équivaut à l'attribut x:Name défini en XAML. Plusieurs autres classes fournissent également des équivalents de niveau propriété pour x:Name, qui est également souvent définie comme une propriété Name. De manière générale, si vous ne parvenez pas à trouver de propriété Name dans la table des membres de l'élément choisi, utilisez x:Name à la place.

L'exemple suivant définit Name sur un élément StackPanel. Un gestionnaire sur un Button dans ce StackPanel référence ensuite le StackPanel par le biais de sa référence d'instance buttonContainer définie par Name.

<StackPanel Name="buttonContainer">


...


  <Button Click="RemoveThis">Click to remove this button</Button>
</StackPanel>
void RemoveThis(object sender, RoutedEventArgs e)
{
    FrameworkElement fe = e.Source as FrameworkElement;
    if (buttonContainer.Children.Contains(fe))
    {
        buttonContainer.Children.Remove(fe);
    }
}

À l'instar d'une variable, le nom d'une instance est gouverné par un concept de portée, de sorte que des noms uniques peuvent être appliqués au sein d'une portée prévisible. La balise primaire qui définit une page définit une portée de nom unique, la limite de cette portée étant l'élément racine de cette page. D'autres sources de balise peuvent toutefois interagir avec une page au moment de l'exécution (styles ou modèles contenus dans des styles) et ces sources possèdent souvent leur propre portée de nom, qui n'est pas nécessaire en connexion avec celle de la page. Pour plus d'informations sur x:Name et les portées de nom, consultez Name, x:Name, attribut ou Portées de nom WPF.

Propriétés et événements attachés

Le XAML spécifie une fonctionnalité du langage qui permet de spécifier certains événements ou certaines propriétés sur un élément quelconque, indépendamment du fait que la propriété ou l'élément existe ou non dans la table des membres de l'élément sur lequel il est défini. La version propriété de cette fonctionnalité est appelée une propriété attachée et la version événement un événement attaché. D'un point de vue conceptuel, les propriétés attachées et les événements attachés peuvent être perçus comme des membres globaux qui peuvent être définis sur tout élément ou classe, indépendamment de sa hiérarchie de classes.

Les propriétés attachées en XAML sont généralement utilisées par le biais de la syntaxe d'attribut. Dans la syntaxe d'attribut, les propriétés attachées sont spécifiées sous la forme TypePropriétaire.NomPropriété. En apparence, cela ressemble à une utilisation d'élément de propriété, mais dans ce cas-ci, le TypePropriétaire que vous spécifiez est toujours d'un type autre que l'élément objet dans lequel la propriété attachée est définie. TypePropriétaire est le type qui fournit les méthodes d'accesseur exigées par un processeur XAML pour obtenir ou définir la valeur de la propriété attachée. Le scénario le plus courant pour les propriétés attachées consiste à permettre à des éléments enfants de signaler une valeur de propriété à leur élément parent.

L'exemple suivant illustre la propriété attachée DockPanel.Dock. La classe DockPanel définit les accesseurs pour DockPanel.Dock et possède par conséquent la propriété attachée. La classe DockPanel inclut également une logique qui itère ses éléments enfants et vérifie de manière spécifique chaque élément pour une valeur définie de DockPanel.Dock. Si une valeur est trouvée, elle est utilisée pendant la disposition pour placer les éléments enfants. L'utilisation de la propriété attachée DockPanel.Dock et de cette fonctionnalité de positionnement est en fait le scénario motivant pour la classe DockPanel.

<DockPanel>
  <Button DockPanel.Dock="Left" Width="100" Height="20">I am on the left</Button>
  <Button DockPanel.Dock="Right" Width="100" Height="20">I am on the right</Button>
</DockPanel>

Dans Windows Presentation Foundation (WPF), toutes les propriétés attachées sont également implémentées sous forme de propriétés de dépendance. Pour plus d'informations, consultez Vue d'ensemble des propriétés attachées.

Les événements attachés utilisent une forme TypePropriétaire.NomÉvénement similaire à la syntaxe d'attribut. Comme pour les événements non attachés, la valeur d'attribut d'un événement attaché en XAML spécifie le nom de la méthode de gestionnaire appelée lorsque l'événement est géré sur l'élément. 

Des événements attachés sont notamment utilisés pour des événements d'entrée de périphérique qui peuvent être gérés sur un élément quelconque (bouton de la souris, par exemple). Mouse.MouseDown est un exemple d'événement attaché de ce type. La plupart des éléments au niveau de l'infrastructure WPF peuvent toutefois utiliser cet événement sans l'utilisation d'événement attaché. En effet, la classe d'élément de base UIElement crée un alias pour l'événement attaché Mouse.MouseDown et expose cet alias dans la table de membres UIElement (en tant que MouseDown). De ce fait, il n'est généralement pas nécessaire de spécifier une syntaxe d'événement attaché dans une page XAML ou une programmation d'applications Windows Presentation Foundation (WPF). Les seules exceptions concernent les cas où vous utilisez des éléments personnalisés ou des éléments objet qui ne dérivent pas de UIElement mais qui conservent une représentation visuelle (c'est très rare). Dans WPF, tous les événements attachés sont également implémentés en tant qu'événements routés. ContentElement expose également des alias pour les événements d'entrée en vue de leur utilisation par le modèle de document dynamique. Pour plus d'informations, consultez Vue d'ensemble des événements routés et Vue d'ensemble des entrées.

Anatomie d'un élément racine de page XAML

Le tableau suivant présente un élément racine de page XAML type ventilé, en montrant les attributs spécifiques d'un élément racine identifiés dans cette rubrique :

<Page

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

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

Espace de noms (WPF) par défaut

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

Espace de noms XAML

x:Class="MyNamespace.MyPageCode"

Déclaration de classe partielle qui connecte la balise à un code-behind quelconque défini dans cette même classe partielle

>

Fin de l'élément objet pour la racine, pas encore fermé car la page contient des éléments enfants

Classes de base et XAML

Le XAML sous-jacent et ses schémas sont une collection de classes qui correspondent à des objets CLR et à des éléments de balisage à utiliser en XAML. Toutes les classes ne peuvent cependant pas être mappées à des éléments. Les classes abstraites, telles que ButtonBase, et certaines classes de base non abstraites sont utilisées pour l'héritage dans le modèle d'objets CLR et ne prennent pas en charge les instructions de balisage XAML correspondantes. Les classes de base, y compris abstraites, sont importantes pour le développement de XAML car chacun des éléments XAML concrets hérite de membres d'une classe de base quelconque dans sa hiérarchie. Souvent, ces membres incluent des propriétés qui peuvent être définies en tant qu'attributs sur l'élément ou des événements qui peuvent être gérés. FrameworkElement est la classe de l'interface utilisateur de base concrète de WPF au niveau de l'infrastructure WPF. Lors de la conception de l'interface utilisateur, vous utiliserez différentes classes de forme, de panneau, de décorateur ou de contrôle, qui dérivent toutes de FrameworkElement. Une classe de base connexe, FrameworkContentElement, prend en charge des éléments orientés document qui fonctionnent bien pour une présentation de mise en page fluide, à l'aide d'API qui reflètent délibérément les API dans FrameworkElement. La combinaison d'attributs au niveau de l'élément et d'un modèle objet CLR vous offre un jeu de propriétés courantes qui sont définissables sur la majorité des éléments XAML concrets, indépendamment du type exact d'élément et de sa classe sous-jacente.

Sécurité XAML

Le XAML est un langage de balisage qui représente directement l'instanciation et l'exécution de l'objet. Par conséquent, les éléments créés en XAML ont la même capacité d'interaction avec les ressources système (accès réseau, E/S du système de fichiers, par exemple) que le code généré correspondant.

WPF prend en charge la sécurité d'accès du code (CAS, Code Access Security) de l'infrastructure de sécurité de l'.NET. Cela signifie que le contenu WPF qui s'exécute dans la zone Internet dispose d'autorisations d'exécution réduites. Le "XAML libre" (pages de XAML non compilé interprétées au moment du chargement par une visionneuse XAML) et l'application du navigateur XAML (XBAP) sont généralement exécutés dans cette zone Internet et utilisent le même jeu d'autorisations. Le XAML chargé dans une application bénéficiant d'un niveau de confiance total a toutefois le même accès aux ressources système que l'application hôte. Pour plus d'informations, consultez Sécurité de confiance partielle de Windows Presentation Foundation.

Chargement de XAML à partir du code

Le XAML peut être utilisé pour définir une interface utilisateur entière, mais il peut parfois s'avérer plus approprié de ne définir qu'une partie de l'interface utilisateur en XAML. Cette fonction peut par exemple être utilisée pour activer une personnalisation partielle, un stockage local d'informations, l'utilisation du XAML pour fournir un objet d'entreprise, ou dans divers autres scénarios. La clé de ces scénarios repose sur la classe XamlReader et sa méthode Load. L'entrée est un fichier XAML et la sortie un objet qui représente l'intégralité de l'arborescence d'objets au moment de l'exécution créée à partir de cette balise. Vous pouvez alors insérer l'objet pour qu'il devienne une propriété d'un autre objet déjà présent dans l'application. Pour autant que la propriété soit une propriété appropriée dans le modèle de contenu qui possède d'éventuelles fonctions d'affichage et qui indique au moteur d'exécution qu'un nouveau contenu a été ajouté dans l'application, vous pouvez très facilement modifier le contenu d'une application en cours d'exécution en le chargeant en XAML. Notez que cette fonction est généralement uniquement disponible dans des applications de confiance totale, en raison des implications évidentes pour la sécurité liées au chargement de fichiers dans des applications en cours d'exécution.

Quoi d'autre ?

Cette rubrique propose une introduction de base à la terminologie et aux concepts de la syntaxe XAML. Pour plus d'informations sur les termes utilisés ici, consultez Terminologie de la syntaxe XAML.

Si ce n'est déjà fait, essayez le didacticiel Mise en route de Windows Presentation Foundation. La création de l'application de balise décrite dans le didacticiel contribuera à renforcer votre compréhension de bon nombre des concepts décrits dans cette rubrique.

WPF utilise un modèle d'application particulier basé sur la classe Application. Pour plus d'informations, consultez Vue d'ensemble de la gestion d'applications.

Génération d'une application WPF (WPF) propose davantage de détails sur la génération d'applications inclusives XAML à partir de la ligne de commande et avec Microsoft Visual Studio.

Vue d'ensemble des propriétés de dépendance donne plus d'informations sur la polyvalence des propriétés dans Windows Presentation Foundation (WPF) et introduit le concept de propriétés de dépendance.

Enfin, un outil d'édition XAML appelé XAMLPad est inclus dans le Kit de développement logiciel (SDK). Vous pouvez l'utiliser pour expérimenter le langage XAML en temps réel.

Voir aussi

Concepts

XAMLPad

XAML et classes personnalisées

Vue d'ensemble des éléments de base

Arborescences dans WPF

Autres ressources

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

Extensions XAML des espaces de noms WPF

Modèles de contenu