Partager via


TypeConverters et XAML

Cette rubrique présente l’objectif de la conversion de type à partir de la chaîne en tant que fonctionnalité de langage XAML générale. Dans le .NET Framework, la TypeConverter classe sert un objectif particulier dans le cadre de l’implémentation d’une classe personnalisée managée qui peut être utilisée comme valeur de propriété dans l’utilisation des attributs XAML. Si vous écrivez une classe personnalisée et que vous souhaitez que les instances de votre classe soient utilisables en tant que valeurs d’attribut settable XAML, vous devrez peut-être appliquer une TypeConverterAttribute classe à votre classe, écrire une classe personnalisée TypeConverter ou les deux.

Concepts de conversion de type

XAML et valeurs de chaîne

Lorsque vous définissez une valeur d’attribut dans un fichier XAML, le type initial de cette valeur est une chaîne en texte pur. Même d'autres primitives, telles que Double, sont initialement considérées comme des chaînes de texte par un processeur XAML.

Un processeur XAML a besoin de deux informations pour traiter une valeur d’attribut. La première information est le type de valeur de la propriété qui est définie. Toute chaîne qui définit une valeur d’attribut et qui est traitée en XAML doit finalement être convertie ou résolue en valeur de ce type. Si la valeur est une primitive comprise par l’analyseur XAML (par exemple, une valeur numérique), une conversion directe de la chaîne est tentée. Si la valeur est une énumération, la chaîne est utilisée pour rechercher une correspondance de nom avec une constante nommée dans cette énumération. Si la valeur n’est ni une primitive comprise par l’analyseur ni une énumération, le type en question doit être en mesure de fournir une instance du type, ou une valeur, en fonction d’une chaîne convertie. Pour ce faire, indiquez une classe de convertisseur de type. Le convertisseur de types est effectivement une classe d’assistance pour fournir des valeurs d’une autre classe, à la fois pour le scénario XAML et potentiellement pour les appels de code dans le code .NET.

Utilisation du comportement de conversion de type existant en XAML

Il se peut que, selon votre connaissance des concepts XAML sous-jacents, vous utilisiez déjà le comportement de conversion de type dans le XAML d'applications de base sans vous en rendre compte. Par exemple, WPF définit littéralement des centaines de propriétés qui prennent une valeur de type Point. Il Point s’agit d’une valeur qui décrit une coordonnée dans un espace de coordonnées à deux dimensions, et elle a vraiment deux propriétés importantes : X et Y. Lorsque vous spécifiez un point en XAML, vous le spécifiez en tant que chaîne avec un délimiteur (généralement une virgule) entre les X valeurs que Y vous fournissez. Par exemple : <LinearGradientBrush StartPoint="0,0" EndPoint="1,1"/>.

Même ce type simple Point et son utilisation simple en XAML impliquent un convertisseur de type. Dans ce cas, il s’agit de la classe PointConverter.

Le convertisseur de type pour Point défini au niveau de la classe simplifie les utilisations de balisage de toutes les propriétés qui prennent Point. Sans convertisseur de type ici, vous avez besoin du balisage beaucoup plus détaillé suivant pour le même exemple illustré précédemment :

<LinearGradientBrush>
  <LinearGradientBrush.StartPoint>
    <Point X="0" Y="0"/>
  </LinearGradientBrush.StartPoint>
  <LinearGradientBrush.EndPoint>
    <Point X="1" Y="1"/>
  </LinearGradientBrush.EndPoint>
</LinearGradientBrush>

L’utilisation de la chaîne de conversion de type ou d’une syntaxe équivalente plus détaillée est généralement un choix de style de codage. Votre workflow d’outils XAML peut également influencer la façon dont les valeurs sont définies. Certains outils XAML ont tendance à émettre la forme la plus verbeuse du balisage, car il est plus facile d’effectuer un aller-retour aux vues du concepteur ou à son propre mécanisme de sérialisation.

Les convertisseurs de types existants peuvent généralement être découverts sur les types WPF et .NET Framework en vérifiant la présence d’une classe (ou d’une propriété) appliquée TypeConverterAttribute. Cet attribut désigne la classe qui sert de convertisseur de type pour les valeurs de ce type, à des fins de XAML ainsi que pour d'autres utilisations potentielles.

Convertisseurs de types et extensions de balisage

Les extensions de balisage et les convertisseurs de types remplissent des rôles orthogonaux en termes de comportement du processeur XAML et les scénarios auxquels ils sont appliqués. Bien que le contexte soit disponible pour les utilisations d’extensions de balisage, le comportement de conversion de type des propriétés où une extension de balisage fournit une valeur n’est généralement pas vérifié dans les implémentations d’extension de balisage. En d’autres termes, même si une extension de balisage retourne une chaîne de texte comme ProvideValue sortie, le comportement de conversion de type sur cette chaîne tel qu’appliqué à un type de propriété ou valeur de propriété spécifique n’est pas appelé, En général, l’objectif d’une extension de balisage est de traiter une chaîne et de retourner un objet sans convertisseur de type impliqué.

Une situation courante où une extension de balisage est nécessaire plutôt qu’un convertisseur de type consiste à faire référence à un objet qui existe déjà. Au mieux, un convertisseur de type sans état ne peut générer qu’une nouvelle instance, qui peut ne pas être souhaitable. Pour plus d’informations sur les extensions de balisage, consultez Extensions de balisage et XAML WPF.

Convertisseurs de type natif

Dans l’implémentation WPF et .NET Framework de l’analyseur XAML, il existe certains types qui ont une gestion de conversion de type native, mais qui ne sont pas des types qui peuvent être considérés de manière conventionnelle comme des primitives. Un exemple de ce type est DateTime. La raison de cette opération est basée sur le fonctionnement de l’architecture .NET Framework : le type DateTime est défini dans mscorlib, la bibliothèque la plus simple dans .NET. DateTime ne peut pas se voir attribuer un attribut provenant d’un autre assembly portant une dépendance (TypeConverterAttribute appartient à System), de sorte que le mécanisme habituel de découverte de convertisseur de type par attribution ne puisse être pris en charge. Au lieu de cela, l’analyseur XAML a une liste de types qui nécessitent un traitement natif de ce type et les traite de la même façon que les véritables primitives. (Dans le cas de DateTime cela implique un appel à Parse.)

Implémentation d’un convertisseur de type

TypeConverter

Dans l’exemple Point donné précédemment, la classe PointConverter a été mentionnée. Pour les implémentations .NET de XAML, tous les convertisseurs de type utilisés à des fins XAML sont des classes qui dérivent de la classe TypeConverterde base . La TypeConverter classe existait dans les versions de .NET Framework qui précèdent l’existence de XAML ; l’une de ses utilisations d’origine était de fournir une conversion de chaîne pour les dialogues de propriété dans les concepteurs visuels. Pour XAML, le rôle de TypeConverter est élargi pour inclure la classe de base pour les conversions de chaîne en chaîne et de chaîne à partir de chaîne, permettant d'analyser une valeur d'attribut sous forme de chaîne et éventuellement de traiter une valeur d'exécution d'une propriété d'objet spécifique en une chaîne afin d'être sérialisée en tant qu'attribut.

TypeConverter définit quatre membres pertinents pour la conversion vers et à partir de chaînes à des fins de traitement XAML :

Parmi ces méthodes, la méthode la plus importante est ConvertFrom. Cette méthode convertit la chaîne d’entrée en type d’objet requis. Strictement parlant, la ConvertFrom méthode peut être implémentée pour convertir un large éventail de types en type de destination prévu du convertisseur, et ainsi servir des objectifs qui s’étendent au-delà du code XAML, comme la prise en charge des conversions au moment de l’exécution, mais à des fins XAML, il s’agit uniquement du chemin de code qui peut traiter une String entrée qui importe.

La méthode la plus importante suivante est ConvertTo. Si une application est convertie en représentation de balisage (par exemple, si elle est enregistrée en XAML en tant que fichier), ConvertTo elle est responsable de la production d’une représentation de balisage. Dans ce cas, le chemin d'accès au code qui est important pour XAML est lorsque vous passez un destinationType et un String.

CanConvertTo et CanConvertFrom sont des méthodes de prise en charge utilisées lorsqu’un service interroge les fonctionnalités de l’implémentation TypeConverter. Vous devez implémenter ces méthodes pour retourner true pour les cas spécifiques au type pris en charge par les méthodes de conversion équivalentes de votre convertisseur. À des fins XAML, cela signifie généralement le type String.

Informations culturelles et convertisseurs de type pour XAML

Chaque TypeConverter implémentation peut avoir sa propre interprétation de ce qui constitue une chaîne valide pour une conversion, et peut également utiliser ou ignorer la description de type passée en tant que paramètres. Il existe une considération importante en ce qui concerne la culture et la conversion de type XAML. L’utilisation de chaînes localisables comme valeurs d’attribut est entièrement prise en charge par XAML. Mais l’utilisation de cette chaîne localisable comme entrée de convertisseur de type avec des exigences culturelles spécifiques n’est pas prise en charge, car les convertisseurs de type pour les valeurs d’attribut XAML impliquent nécessairement un comportement d’analyse fixé sur le langage, utilisant la culture en-US. Pour plus d’informations sur les raisons de conception de cette restriction, vous devez consulter la spécification du langage XAML ([MS-XAML].

Par exemple, dans certaines cultures, une virgule est utilisée comme délimiteur pour le point décimal des nombres. Cela va entrer en conflit avec le comportement que de nombreux convertisseurs de type XAML WPF ont, qui consiste à utiliser une virgule comme délimiteur (en fonction de précédents historiques tels que le formulaire X,Y commun ou les listes délimitées par des virgules). Même en passant une culture dans l'environnement XAML (en paramétrant Language ou xml:lang à la culture sl-SI, exemplaire d'une culture qui utilise une virgule pour les décimales de cette manière) ne résout pas le problème.

Implémentation de ConvertFrom

Pour être utilisable en tant qu’implémentation TypeConverter qui prend en charge XAML, la méthode ConvertFrom pour ce convertisseur doit accepter une chaîne comme paramètre value. Si la chaîne est au format valide et peut être convertie par l’implémentation TypeConverter, l’objet retourné doit supporter une conversion vers le type attendu par la propriété. Sinon, l’implémentation ConvertFrom doit retourner null.

Chaque TypeConverter implémentation peut avoir sa propre interprétation de ce qui constitue une chaîne valide pour une conversion, et peut également utiliser ou ignorer la description de type ou les contextes de culture passés en tant que paramètres. Toutefois, le traitement XAML WPF peut ne pas passer de valeurs au contexte de description de type dans tous les cas, et peut également ne pas passer la culture définie par xml:lang.

Remarque

N’utilisez pas les caractères accolades, en particulier {, comme élément possible de votre format de chaîne. Ces caractères sont réservés comme entrée et sortie pour une séquence d’extension de balisage.

Implémentation de ConvertTo

ConvertTo est potentiellement utilisé pour la prise en charge de la sérialisation. La prise en charge de la sérialisation via ConvertTo pour votre type personnalisé et son convertisseur de type n'est pas une spécification absolue. Toutefois, si vous implémentez un contrôle ou que vous utilisez la sérialisation dans le cadre des fonctionnalités ou de la conception de votre classe, vous devez implémenter ConvertTo.

Pour être utilisable en tant qu’implémentation TypeConverter prenant en charge XAML, la ConvertTo méthode de ce convertisseur doit accepter une instance du type (ou une valeur) prise en charge en tant que value paramètre. Lorsque le paramètre destinationType est de type String, l’objet retourné doit pouvoir être casté en String. La chaîne retournée doit représenter une valeur sérialisée de value. Dans l’idéal, le format de sérialisation que vous choisissez doit être capable de générer la même valeur si cette chaîne a été passée à l’implémentation ConvertFrom du même convertisseur, sans perte significative d’informations.

Si la valeur ne peut pas être sérialisée ou si le convertisseur ne prend pas en charge la sérialisation, l’implémentation ConvertTo doit retourner nullet est autorisée à lever une exception dans ce cas. Toutefois, si vous levez des exceptions, vous devez signaler l’incapacité d’utiliser cette conversion dans le cadre de votre CanConvertTo implémentation afin que la meilleure pratique de vérifier d'abord avec CanConvertTo pour éviter les exceptions soit prise en charge.

Si destinationType le paramètre n’est pas de type String, vous pouvez choisir votre propre gestion du convertisseur. En règle générale, vous revenez à la gestion de l'implémentation de base, qui, au niveau le plus fondamental, ConvertTo déclenche une exception spécifique.

Implémentation de CanConvertTo

Votre implémentation de CanConvertTo doit retourner la valeur true pour destinationType de type String, et sinon déférer à l'implémentation de base.

Implémentation de CanConvertFrom

Votre implémentation de CanConvertFrom doit retourner la valeur true pour sourceType de type String, et sinon déférer à l'implémentation de base.

Application de l'attribut TypeConverterAttribute

Pour que votre convertisseur de type personnalisé soit utilisé en tant que convertisseur de type actif pour une classe personnalisée par un processeur XAML, vous devez appliquer l'attribut TypeConverterAttribute à la définition de votre classe. La ConverterTypeName que vous spécifiez via l’attribut doit être le nom de type de votre convertisseur de type personnalisé. Avec cet attribut appliqué, lorsqu’un processeur XAML gère les valeurs où le type de propriété utilise votre type de classe personnalisé, il peut entrer des chaînes et retourner des instances d’objet.

Vous pouvez également fournir un convertisseur de type en fonction de la propriété. Au lieu d’appliquer une TypeConverterAttribute à la définition de classe, appliquez-la à une définition de propriété (la définition principale, et non les implémentations get/set dans celle-ci). Le type de la propriété doit correspondre au type traité par votre convertisseur de type personnalisé. Avec cet attribut appliqué, lorsqu’un processeur XAML gère les valeurs de cette propriété, il peut traiter les chaînes d’entrée et retourner des instances d’objet. La technique de convertisseur de type par propriété est particulièrement utile si vous choisissez d’utiliser un type de propriété à partir de Microsoft .NET Framework ou d’une autre bibliothèque où vous ne pouvez pas contrôler la définition de classe et que vous ne pouvez pas y appliquer TypeConverterAttribute.

Voir aussi