Vue d’ensemble des convertisseurs de types pour XAML

Les convertisseurs de type fournissent la logique nécessaire à un writer d'objet qui convertit une chaîne de balisage XAML en objets particuliers d'un graphique d'objets. Dans les services XAML .NET, le convertisseur de type doit être une classe qui dérive de TypeConverter. Certains convertisseurs prennent également en charge le chemin d'enregistrement XAML et peuvent être utilisés pour sérialiser un objet sous forme de chaîne dans le balisage de sérialisation. Cette rubrique décrit comment et quand les convertisseurs de type en XAML sont appelés, et fournit des conseils d'implémentation pour les substitutions de méthode de TypeConverter.

Concepts de conversion de type

Les sections suivantes expliquent les concepts de base sur la façon dont XAML utilise des chaînes et comment les enregistreurs d’objets dans les services XAML .NET utilisent des convertisseurs de types pour traiter certaines des valeurs de chaîne rencontrées dans une source XAML.

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 dans un sens général et une valeur d'attribut de chaîne dans le sens de XML. Même les autres primitives telles que Double sont initialement des chaînes pour un processeur XAML.

Dans la plupart des cas, un processeur XAML a besoin de deux éléments d'informations pour 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 de l'attribut référence une énumération, la chaîne fournie est utilisée pour rechercher une correspondance de nom avec une constante nommée dans cette énumération. Si la valeur n’est pas une primitive comprise par l’analyseur ou un nom constant d’une énumération, le type applicable doit être en mesure de fournir une valeur ou une référence basée sur une chaîne convertie.

Remarque

Les directives de langage XAML n'utilisent pas de convertisseur de type.

Convertisseurs de type et extensions de balisage

Les utilisations d'extension de balisage doivent être gérées par un processeur XAML avant qu'il ne recherche le type de propriété et d'autres considérations. Par exemple, si une propriété définie en tant qu'attribut a généralement une conversion de type, mais que dans un cas particulier, elle est définie par une utilisation d'extension de balisage, le comportement d'extension de balisage est traité en premier. Faire référence à un objet existant constitue une situation courante où il est nécessaire d'utiliser une extension de balisage. Pour ce scénario, un convertisseur de type sans état peut uniquement générer une nouvelle instance, ce qui n'est peut-être pas souhaitable. Pour plus d’informations sur les extensions de balisage, consultez Markup Extensions for XAML Overview.

Convertisseurs de type natif

Dans les implémentations des services XAML Windows Presentation Foundation (WPF) et .NET, certains types CLR ont une gestion de conversion de type native. Toutefois, ces types CLR ne sont pas considérés de manière conventionnelle comme des primitives. Un exemple d'un tel type est DateTime. L'une des raisons réside dans le fonctionnement de l'architecture .NET Framework : le type DateTime est défini dans mscorlib, la bibliothèque la plus élémentaire du .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). Par conséquent, le mécanisme de découverte de convertisseur de type habituel en attribut ne peut 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, ce traitement implique un appel à Parse.

Implémentation d'un convertisseur de type

Les sections suivantes traitent de l'API de la classe TypeConverter .

TypeConverter

Sous services XAML .NET, tous les convertisseurs de type utilisés à des fins XAML sont des classes qui dérivent de la classe TypeConverterde base . La classe TypeConverter existait dans les versions du .NET Framework antérieures à l'introduction de XAML ; l'un des scénarios TypeConverter d'origine consistait à fournir une conversion de chaînes pour les éditeurs de propriétés dans les concepteurs visuels.

Pour XAML, le rôle de TypeConverter a été étendu. Aux fins du langage XAML, TypeConverter est la classe de base permettant la prise en charge de certaines conversions en chaînes et à partir de chaînes. Les conversions à partir de chaînes permettent d'analyser une valeur d'attribut de chaîne à partir du code XAML. Les conversions en chaînes permettent de reconvertir une valeur d'exécution d'une propriété d'objet particulière en attribut en XAML pour la sérialisation.

TypeConverter définit quatre membres qui sont utiles pour la conversion en chaînes et à partir de chaînes à des fins de traitement XAML :

Parmi ces membres, la méthode la plus importante est ConvertFrom, qui convertit la chaîne d'entrée en type d'objet requis. La méthode ConvertFrom peut être implémentée pour convertir une plage plus large de types vers le type de destination prévu du convertisseur. Par conséquent, elle peut remplir des fonctions qui dépassent le cadre du langage XAML, telles que la prise en charge des conversions au moment de l'exécution. Toutefois, pour l'utilisation de XAML, seul le chemin de code capable de traiter une entrée String est important.

La deuxième méthode la plus importante 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 impliquée dans le scénario plus large d’un enregistreur de texte XAML pour produire une représentation de balisage. Dans ce cas, le chemin de code important pour XAML est lorsque l'appelant passe un destinationType de 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 implémentation TypeConverter peut interpréter de façon unique ce qui constitue une chaîne valide dans le cadre d'une conversion ; elle peut également utiliser ou ignorer la description de type passée en tant que paramètres. Considération importante relative à la culture et à la conversion de type XAML : bien que l'utilisation de chaînes localisables en tant que valeurs d'attribut soit prise en charge par XAML, vous ne pouvez pas employer ces chaînes localisables comme entrée de convertisseur de type avec des spécifications de culture particulières. Cette restriction est due au fait que les convertisseurs de types des valeurs d'attribut XAML impliquent un comportement de traitement XAML de langage fixe qui utilise la culture en-US . Pour plus d’informations sur les raisons de conception de cette restriction, consultez la spécification du langage XAML ([MS-XAML]) ou la vue d’ensemble de la globalisation et de la localisation WPF.

Par exemple, certaines cultures utilisent une virgule au lieu d'un point comme séparateur décimal pour les nombres sous forme de chaîne, ce qui peut poser un problème. Cette utilisation crée un conflit avec le comportement de nombreux convertisseurs de type existants, qui consiste à utiliser une virgule comme délimiteur. Le passage d'une culture via xml:lang dans le code XAML environnant 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 a un format valide et qu'elle peut être convertie par l'implémentation de 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 implémentation de TypeConverter peut interpréter de façon unique ce qui constitue une chaîne valide dans le cadre d'une conversion ; elle 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 ne passe pas nécessairement des valeurs au contexte de description de type dans tous les cas, ni de culture en fonction de xml:lang.

Remarque

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

Il est approprié de lever une exception lorsque votre convertisseur de types doit avoir accès à un service XAML à partir de l’enregistreur d’objets des services XAML .NET, mais que l’appel GetService effectué par rapport au contexte ne retourne pas ce service.

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 de TypeConverter qui prend en charge XAML, la méthode ConvertTo de ce convertisseur doit accepter une instance du type (ou une valeur) prise en charge comme paramètre value . 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. Idéalement, le format de sérialisation que vous choisissez doit pouvoir générer la même valeur que si cette chaîne était passée à l'implémentation de ConvertFrom du même convertisseur, sans perte significative d'informations.

Si la valeur ne peut pas être sérialisée ou que le convertisseur ne prend pas en charge la sérialisation, l'implémentation de ConvertTo doit retourner la valeur null et peut lever une exception. Toutefois, si vous levez des exceptions, vous devez signaler que cette conversion ne peut pas être utilisée dans le cadre de votre implémentation de CanConvertTo afin que la meilleure pratique qui consiste à effectuer d'abord une vérification avec CanConvertTo pour éviter les exceptions soit prise en charge.

Si le paramètre destinationType n'est pas de type String, vous pouvez choisir votre propre gestion de convertisseur. En général, vous rétablissez le traitement de l'implémentation de base, ce qui, dans la méthode ConvertTo de base, lève une exception spécifique.

Il est approprié de lever une exception lorsque votre convertisseur de types doit avoir accès à un service XAML à partir de l’enregistreur d’objets des services XAML .NET, mais que l’appel GetService effectué par rapport au contexte ne retourne pas ce service.

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. Ne levez pas d'exceptions à partir de la méthode CanConvertFrom.

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. Ne levez pas d'exceptions à partir de la méthode CanConvertTo.

Application de TypeConverterAttribute

Pour que votre convertisseur de type personnalisé soit utilisé comme convertisseur de type agissant pour une classe personnalisée par les services XAML .NET, 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é. Si vous appliquez cet attribut, lorsqu'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 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 un TypeConverterAttribute .

Pour fournir un comportement de conversion de type pour un membre attaché personnalisé, appliquez TypeConverterAttribute à la méthode Get d'accesseur du modèle d'implémentation du membre attaché.

Accès au contexte de fournisseur de services à partir d'une implémentation de l'extension du balisage

Les services disponibles sont les mêmes pour tous les convertisseurs de valeurs. La seule différence réside dans le mode de réception du contexte de service par chaque convertisseur de valeurs. L’accès aux services et les services disponibles sont documentés dans la rubrique Type Converters and Markup Extensions for XAML.

Convertisseurs de type et flux de nœud XAML

Si vous utilisez un flux de nœud XAML, l'action d'un convertisseur de type n'est pas encore exécutée ou n'a pas encore produit de résultat final. Dans un chemin de chargement, la chaîne d'attribut dont le type doit finalement être converti pour qu'elle puisse être chargée demeure sous la forme d'une valeur de texte dans un membre de début et un membre de fin. Le convertisseur de type qui est finalement requis pour cette opération peut être déterminé à l'aide de la propriété XamlMember.TypeConverter . Toutefois, l'obtention d'une valeur valide à partir de XamlMember.TypeConverter repose sur la disponibilité d'un contexte de schéma XAML permettant d'accéder à ces informations via le membre sous-jacent ou le type de la valeur d'objet que le membre utilise. L'appel réel du comportement de conversion de type requiert également le contexte de schéma XAML car cette opération nécessite un mappage de type et la création d'une instance de convertisseur.

Voir aussi