TypeConverters et XAML

Cette rubrique présente l’objectif de la conversion de types de chaîne comme une fonctionnalité générale du langage XAML. 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

Quand 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 les chaînes de texte initialement dans un processeur XAML.

Un processeur XAML a besoin de deux types d’informations pour pouvoir traiter une valeur d’attribut. Le premier élément d'information est le type valeur de la propriété à définir. N'importe quelle chaîne qui définit une valeur d'attribut et qui est traitée en XAML doit au final être convertie ou résolue en une valeur de ce type. Si la valeur est une primitive comprise par l'analyseur XAML (telle qu'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 à 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 pouvoir fournir une instance du type ou une valeur, en fonction d’une chaîne convertie. Pour cela, vous devez indiquer une classe de convertisseur de type. Le convertisseur de type est une classe d’assistance qui sert à fournir des valeurs d’une autre classe, pour le scénario XAML et éventuellement pour les appels de code dans le code .NET.

Utilisation du comportement de conversion de types existant en XAML

En fonction de votre connaissance des concepts XAML sous-jacents, il se peut que vous utilisiez déjà un comportement de conversion de types dans des applications XAML 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 et Point 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 un convertisseur de type ici, vous auriez besoin de la balise suivante beaucoup plus détaillée pour l’exemple indiqué 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 d’une chaîne de conversion de type ou d’une syntaxe équivalente plus détaillée est une question de style de codage. Votre workflow d’outils XAML peut également influencer la définition des valeurs. Certains outils XAML ont tendance à émettre la forme la plus détaillée du balisage, car il est plus facile de parcourir les 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 case activée d’une classe (ou d’une propriété) pour la présence d’une TypeConverterAttributeapplication. Cet attribut nomme la classe qui est le convertisseur de type de prise en charge pour les valeurs de ce type, pour les besoins XAML et éventuellement d’autres usages.

Convertisseurs de type et extensions de balisage

Les extensions de balisage et les convertisseurs de types remplissent des rôles orthogonaux quant au comportement du processeur XAML et aux scénarios auxquels ils s’appliquent. Bien que le contexte soit disponible pour les extensions de balisage, le comportement de la 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 sortie ProvideValue, le comportement de conversion de type associé à cette chaîne tel qu’il est appliqué à une propriété ou un type de valeur de propriété spécifique n’est pas appelé. En général, la fonction d’une extension de balisage consiste à traiter une chaîne et retourner un objet sans faire appel à un convertisseur de type.

Dans le cadre de la création d’une référence à un objet existant, il est courant d’utiliser une extension de balisage à la place d’un convertisseur de type. Au mieux, un convertisseur de type sans état générerait uniquement une nouvelle instance, ce 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 une implémentation WPF et .NET Framework de l’analyseur XAML, certains types gèrent nativement la conversion de type ; cependant, ces types ne sont pas traditionnellement considérés comme des primitives. Un exemple d'un tel 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 n’est pas autorisé à être attribué avec un attribut provenant d’un autre assembly qui introduit une dépendance (TypeConverterAttribute est de System) afin que le mécanisme de découverte de convertisseur de type habituel en attribut ne puisse pas être pris en charge. À la place, l’analyseur XAML dispose d’une liste des types qui doivent faire l’objet d’un traitement natif et traite ces types 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 d’extension TypeConverter est d’inclure la classe de base pour les conversions de chaînes et de chaînes qui permettent d’analyser une valeur d’attribut de chaîne, et éventuellement de traiter une valeur d’exécution d’une propriété d’objet particulière dans une chaîne pour la sérialisation 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 exigé. 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 importe pour XAML est lorsque vous passez un destinationType .String

CanConvertTo et CanConvertFrom sont des méthodes de support utilisées lorsqu'un service interroge les fonctions de l'implémentation TypeConverter . Vous devez implémenter ces méthodes pour retourner true dans des cas spécifiques au type pris en charge par les méthodes de conversion correspondantes de votre convertisseur. Pour le langage XAML, cela correspond généralement au type String .

Informations de culture 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. Vous devez tenir compte d’un élément fondamental en ce qui concerne la culture et la conversion de type XAML. L’utilisation de chaînes localisables comme valeurs d’attribut est intégralement prise en charge par XAML. Mais l’utilisation de cette chaîne localisable comme entrée de convertisseur de type avec des spécifications de culture spécifiques n’est pas prise en charge, car les convertisseurs de types pour les valeurs d’attribut XAML impliquent un comportement d’analyse de langage fixe, à l’aide de 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, certaines cultures utilisent une virgule comme séparateur décimal pour les nombres, ce qui peut être un problème. Cela crée un conflit avec de nombreux convertisseurs de types XAML WPF qui utilisent une virgule comme séparateur (pour des raisons historiques : forme X,Y courante ou listes délimitées par des virgules). Même le passage d’une culture dans le XAML voisin (affectation à Language ou xml:lang de la culture sl-SI, un exemple de culture utilisant une virgule comme séparateur décimal) ne résout pas le problème.

Implémentation de ConvertFrom

Pour être utilisable en tant qu'implémentation TypeConverter qui prend en charge le code XAML, la méthode ConvertFrom du convertisseur doit accepter une chaîne comme paramètre value . Si la chaîne était au format valide et peut être convertie par l’implémentation TypeConverter , l’objet retourné doit prendre en charge un cast 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. Cependant, le traitement XAML WPF peut ne pas passer de valeurs au contexte de description de type dans tous les cas, et également ne pas passer la culture en fonction de xml:lang.

Remarque

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

Implémentation de ConvertTo

La méthodeConvertTo peut être utilisée pour assurer 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 la 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 est le destinationType type String, l’objet retourné doit être converti en tant que 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 lèvez 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 case activée avec CanConvertTo d’abord pour éviter les exceptions est 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, dans la base la plus, 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 TypeConverterAttribute

Pour que votre convertisseur de type personnalisé soit utilisé comme convertisseur de type agissant pour une classe personnalisée par un processeur XAML, vous devez appliquer la TypeConverterAttribute définition de votre classe. La propriété ConverterTypeName que vous spécifiez via l'attribut doit être le nom de type du convertisseur de type personnalisé. Une fois cet attribut appliqué, quand un processeur XAML gère des valeurs où le type de propriété utilise votre type de classe personnalisée, 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 un TypeConverterAttribute à la définition de classe, appliquez-le à une définition de propriété (c'est-à-dire à la définition principale, et non pas aux implémentations de get/set qu'elle contient). 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 des valeurs de cette propriété, il peut traiter des 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 ne peut pas y appliquer.TypeConverterAttribute

Voir aussi