Schémas d’espace de noms personnalisés XAML dans Xamarin.Forms

Les types d’une bibliothèque peuvent être référencés en XAML en déclarant un espace de noms XAML pour la bibliothèque, avec la déclaration d’espace de noms spécifiant le nom de l’espace de noms ClR (Common Language Runtime) et un nom d’assembly :

<ContentPage ...
             xmlns:controls="clr-namespace:MyCompany.Controls;assembly=MyCompany.Controls">
    ...
</ContentPage>

Toutefois, la spécification d’un espace de noms CLR et d’un nom d’assembly dans une xmlns définition peut être maladroite et sujette à des erreurs. En outre, plusieurs déclarations d’espace de noms XAML peuvent être requises si la bibliothèque contient des types dans plusieurs espaces de noms.

Une autre approche consiste à définir un schéma d’espace de noms personnalisé, tel que http://mycompany.com/schemas/controls, qui est mappé à un ou plusieurs espaces de noms CLR. Cela permet à une seule déclaration d’espace de noms XAML de référencer tous les types d’un assembly, même s’ils se trouvent dans différents espaces de noms. Il permet également à une seule déclaration d’espace de noms XAML de référencer des types dans plusieurs assemblys.

Pour plus d’informations sur les espaces de noms XAML, consultez Espaces de noms XAML dans Xamarin.Forms.

Définition d’un schéma d’espace de noms personnalisé

L’exemple d’application contient une bibliothèque qui expose certains contrôles simples, tels que CircleButton:

using Xamarin.Forms;

namespace MyCompany.Controls
{
    public class CircleButton : Button
    {
        ...
    }
}

Tous les contrôles de la bibliothèque résident dans l’espace MyCompany.Controls de noms. Ces contrôles peuvent être exposés à un assembly appelant via un schéma d’espace de noms personnalisé.

Un schéma d’espace de noms personnalisé est défini avec la XmlnsDefinitionAttribute classe, qui spécifie le mappage entre un espace de noms XAML et un ou plusieurs espaces de noms CLR. Il XmlnsDefinitionAttribute prend deux arguments : le nom de l’espace de noms XAML et le nom de l’espace de noms CLR. Le nom de l’espace de noms XAML est stocké dans la XmlnsDefinitionAttribute.XmlNamespace propriété et le nom de l’espace de noms CLR est stocké dans la XmlnsDefinitionAttribute.ClrNamespace propriété.

Remarque

La XmlnsDefinitionAttribute classe a également une propriété nommée AssemblyName, qui peut éventuellement être définie sur le nom de l’assembly. Cela est obligatoire uniquement lorsqu’un espace de noms CLR référencé à partir d’un XmlnsDefinitionAttribute est dans un assembly externe.

La XmlnsDefinitionAttribute valeur doit être définie au niveau de l’assembly dans le projet qui contient les espaces de noms CLR qui seront mappés dans le schéma d’espace de noms personnalisé. L’exemple suivant montre le fichier AssemblyInfo.cs de l’exemple d’application :

using Xamarin.Forms;
using MyCompany.Controls;

[assembly: Preserve]
[assembly: XmlnsDefinition("http://mycompany.com/schemas/controls", "MyCompany.Controls")]

Ce code crée un schéma d’espace de noms personnalisé qui mappe l’URL http://mycompany.com/schemas/controls à l’espace MyCompany.Controls de noms CLR. En outre, l’attribut Preserve est spécifié sur l’assembly pour vous assurer que l’éditeur de liens conserve tous les types de l’assembly.

Important

L’attribut Preserve doit être appliqué aux classes de l’assembly mappées via le schéma d’espace de noms personnalisé ou appliquées à l’assembly entier.

Le schéma d’espace de noms personnalisé peut ensuite être utilisé pour la résolution de types dans les fichiers XAML.

Consommation d’un schéma d’espace de noms personnalisé

Pour consommer des types à partir du schéma d’espace de noms personnalisé, le compilateur XAML requiert qu’il existe une référence de code de l’assembly qui consomme les types, à l’assembly qui définit les types. Pour ce faire, ajoutez une classe contenant une Init méthode à l’assembly qui définit les types qui seront consommés via XAML :

namespace MyCompany.Controls
{
    public static class Controls
    {
        public static void Init()
        {
        }
    }
}

La Init méthode peut ensuite être appelée à partir de l’assembly qui consomme des types à partir du schéma d’espace de noms personnalisé :

using Xamarin.Forms;
using MyCompany.Controls;

namespace CustomNamespaceSchemaDemo
{
    public partial class MainPage : ContentPage
    {
        public MainPage()
        {
            Controls.Init();
            InitializeComponent();
        }
    }
}

Avertissement

Si vous ne parvenez pas à inclure une telle référence de code, le compilateur XAML ne peut pas localiser l’assembly contenant les types de schémas d’espace de noms personnalisés.

Pour consommer le CircleButton contrôle, un espace de noms XAML est déclaré, avec la déclaration d’espace de noms spécifiant l’URL du schéma d’espace de noms personnalisé :

<ContentPage xmlns="http://xamarin.com/schemas/2014/forms"
             xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
             xmlns:controls="http://mycompany.com/schemas/controls"
             x:Class="CustomNamespaceSchemaDemo.MainPage">
    <StackLayout Margin="20,35,20,20">
        ...
        <controls:CircleButton Text="+"
                               BackgroundColor="Fuchsia"
                               BorderColor="Black"
                               CircleDiameter="100" />
        <controls:CircleButton Text="-"
                               BackgroundColor="Teal"
                               BorderColor="Silver"
                               CircleDiameter="70" />
        ...
    </StackLayout>
</ContentPage>

CircleButton les instances peuvent ensuite être ajoutées au ContentPage fichier en les déclarant avec le préfixe d’espace controls de noms.

Pour rechercher les types de schémas d’espace de noms personnalisés, Xamarin.Forms recherchez les assemblys référencés pour les XmlnsDefinitionAttribute instances. Si l’attribut xmlns d’un élément d’un fichier XAML correspond à la XmlNamespace valeur de propriété dans un XmlnsDefinitionAttribute, Xamarin.Forms tente d’utiliser la XmlnsDefinitionAttribute.ClrNamespace valeur de propriété pour la résolution du type. En cas d’échec de la résolution de type, Xamarin.Forms continuez à tenter la résolution de type en fonction des instances correspondantes XmlnsDefinitionAttribute supplémentaires.

Le résultat est que deux CircleButton instances sont affichées :

Boutons de cercle