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 classe TypeConverter sert d’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 un TypeConverterAttribute à votre classe, écrire une classe de TypeConverter personnalisée, ou les deux.

Concepts de Conversion de Type

Valeurs 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 des chaînes de texte vers 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 en cours de définition. 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

Selon votre connaissance des concepts XAML sous-jacents, vous utilisez peut-être déjà le comportement de conversion de type dans le XAML des applications basiques sans le réaliser. Par exemple, WPF définit littéralement des centaines de propriétés qui prennent une valeur de type Point. Un Point est une valeur qui décrit une coordonnée dans un espace de coordonnées à deux dimensions, et il 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 valeurs X et Y que vous fournissez. Par exemple : <LinearGradientBrush StartPoint="0,0" EndPoint="1,1"/>.

Même ce type simple de 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 cela facilite l'aller-retour vers les vues de conception 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 une classe (ou propriété) pour la présence d’un TypeConverterAttributeappliqué. Cet attribut nomme la classe qui est le convertisseur de type de prise en charge pour les valeurs de ce type, pour des raisons XAML ainsi que pour d'autres raisons éventuelles.

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 en tant que sortie ProvideValue, 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 leWPF XAML.

Convertisseurs de types natifs

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 n’est pas autorisé à être attribué avec un attribut provenant d’un autre assembly qui introduit une dépendance (TypeConverterAttribute provient de System) de sorte que le mécanisme de découverte de convertisseur de type habituel en attribut ne peut pas ê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

Convertisseur de type

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 de base TypeConverter. La classe TypeConverter existait dans les versions de .NET Framework qui précèdent l’existence de XAML ; l’une de ses utilisations originales é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 étendu pour inclure la classe de base pour les conversions vers et depuis des chaînes, qui permettent d’analyser une valeur d’attribut de chaîne et éventuellement de convertir une valeur au moment de l'exécution d’une propriété d’objet particulière en 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 :

De 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 méthode ConvertFrom 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à de 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 entrée String 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 est responsable de la production d’une représentation de balisage. Dans ce cas, le chemin de code important pour XAML est celui où vous passez un destinationType de 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 implémentation de TypeConverter 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 pour le convertisseur de type avec des exigences de culture 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 dans une langue fixe, en 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, la culture peut poser problème, certaines cultures utilisent une virgule comme séparateur décimal pour les 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 le XAML environnant (définir Language ou xml:lang à la culture sl-SI, un exemple de culture qui utilise une virgule pour les décimales de cette façon) 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 permettre une conversion de type vers le type attendu par la propriété. Sinon, l’implémentation ConvertFrom doit retourner null.

Chaque implémentation TypeConverter 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, dans certains cas, le traitement XAML de WPF peut ne pas transmettre de valeurs au contexte de description de type et peut également ne pas transmettre la culture en fonction de xml:lang.

Note

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. Le support de la sérialisation via ConvertTo pour votre type personnalisé et son convertisseur de types n'est pas une obligation 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 qui prend en charge XAML, la méthode ConvertTo pour ce convertisseur doit accepter une instance du type (ou une valeur) prise en charge comme paramètre value. Lorsque le paramètre destinationType est le type String, l’objet retourné doit être casté 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 levez des exceptions, vous devez signaler l’incapacité d’utiliser cette conversion dans le cadre de votre implémentation de CanConvertTo afin que la meilleure pratique de vérifier avec CanConvertTo d’abord pour éviter les exceptions soit prise en charge.

Si destinationType 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 le ConvertTo le plus bas, déclenche une exception spécifique.

Implémentation de CanConvertTo

Votre implémentation de CanConvertTo doit retourner true pour destinationType de type Stringet sinon, déléguer à l'implémentation de base.

Implémentation de CanConvertFrom

Votre implémentation de CanConvertFrom doit retourner true pour sourceType de type String, et sinon se référer à l’implémentation de base.

Utilisation 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 à votre définition de 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 pour chaque 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 du convertisseur de type par propriété individuelle est particulièrement utile si vous choisissez d’utiliser un type de propriété provenant de Microsoft .NET Framework ou d’une autre bibliothèque où vous ne pouvez pas contrôler la définition de la classe et ne pouvez pas y appliquer un TypeConverterAttribute.

Voir aussi