Share via


Benutzerdefinierte XAML-Namespaceschemas in Xamarin.Forms

Auf Typen in einer Bibliothek kann in XAML verwiesen werden, indem ein XAML-Namespace für die Bibliothek deklariert wird, wobei die Namespacedeklaration den Namespacenamen der Common Language Runtime (CLR) und einen Assemblynamen angibt:

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

Die Angabe eines CLR-Namespace und eines Assemblynamens in einer xmlns-Definition kann jedoch umständlich und fehleranfällig sein. Darüber hinaus sind möglicherweise mehrere XAML-Namespacedeklarationen erforderlich, wenn die Bibliothek Typen in mehreren Namespaces enthält.

Ein alternativer Ansatz ist die Definition eines benutzerdefinierten Namespace-Schemas, wie z. B. http://mycompany.com/schemas/controls, das auf einen oder mehrere CLR-Namespaces abgebildet wird. Dadurch kann eine einzelne XAML-Namespacedeklaration auf alle Typen in einer Assembly verweisen, auch wenn sie sich in verschiedenen Namespaces befinden. Außerdem kann eine einzelne XAML-Namespacedeklaration auf Typen in mehreren Assemblys verweisen.

Weitere Informationen zu XAML-Namespaces finden Sie unter XAML-Namespaces in Xamarin.Forms.

Definieren eines benutzerdefinierten Namespaceschemas

Die Beispielanwendung enthält eine Bibliothek, die einige einfache Steuerelemente, wie CircleButton, bereitstellt:

using Xamarin.Forms;

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

Alle Steuerelemente in der Bibliothek befinden sich im Namespace MyCompany.Controls. Diese Steuerelemente können für eine aufrufende Assembly über ein benutzerdefiniertes Namespaceschema verfügbar gemacht werden.

Ein benutzerdefiniertes Namespaceschema wird mit der Klasse XmlnsDefinitionAttribute definiert, die die Zuordnung zwischen einem XAML-Namespace und einem oder mehreren CLR-Namespaces festlegt. XmlnsDefinitionAttribute verwendet zwei Argumente: den XAML-Namespacenamen und den CLR-Namespacenamen. Der XAML-Namespacename wird in der XmlnsDefinitionAttribute.XmlNamespace-Eigenschaft gespeichert und der CLR-Namespacename in der XmlnsDefinitionAttribute.ClrNamespace-Eigenschaft.

Hinweis

Die Klasse XmlnsDefinitionAttribute verfügt außerdem über eine Eigenschaft namens AssemblyName, die optional auf den Namen der Assembly gesetzt werden kann. Dies ist nur erforderlich, wenn ein CLR-Namespace, auf den von einem XmlnsDefinitionAttribute verwiesen wird, in einer externen Assembly enthalten ist.

XmlnsDefinitionAttribute sollte auf der Assemblyebene im Projekt definiert werden, das die CLR-Namespaces enthält, die im benutzerdefinierten Namespaceschema abgebildet werden. Das folgende Beispiel zeigt die AssemblyInfo.cs Datei aus der Beispielanwendung:

using Xamarin.Forms;
using MyCompany.Controls;

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

Dieser Code erstellt ein benutzerdefiniertes Namespaceschema, das die URL http://mycompany.com/schemas/controls dem CLR-Namespace MyCompany.Controls zuordnet. Außerdem wird das Preserve-Attribut in der Assembly angegeben, um sicherzustellen, dass der Linker alle Typen in der Assembly beibehält.

Wichtig

Das Preserve-Attribut sollte auf Klassen in der Assembly angewendet werden, die durch das benutzerdefinierte Namespaceschema abgebildet werden, oder auf die gesamte Assembly angewendet werden.

Das benutzerdefinierte Namespaceschema kann dann für die Typauflösung in XAML-Dateien verwendet werden.

Verwenden eines benutzerdefinierten Namespaceschemas

Um Typen aus dem benutzerdefinierten Namespaceschema zu verwenden, benötigt der XAML-Compiler eine Codereferenz von der Assembly, die die Typen verwendet, zu der Assembly, die die Typen definiert. Dazu fügen Sie der Assembly eine Klasse mit einer Init-Methode hinzu, die die Typen definiert, die über XAML genutzt werden sollen:

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

Die Init-Methode kann dann von der Assembly aufgerufen werden, die Typen aus dem benutzerdefinierten Namespaceschema nutzt:

using Xamarin.Forms;
using MyCompany.Controls;

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

Warnung

Wenn Sie eine solche Codereferenz nicht angeben, kann der XAML-Compiler die Assembly, die die benutzerdefinierten Namespaceschematypen enthält, nicht finden.

Um das CircleButton-Steuerelement zu verwenden, wird ein XAML-Namespace deklariert, wobei die Namespacedeklaration die URL des benutzerdefinierten Namespaceschemas angibt:

<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-Instanzen können dann zu ContentPage hinzugefügt werden, indem sie mit dem controls-Namespacepräfix deklariert werden.

Um die benutzerdefinierten Namespaceschematypen zu finden, Xamarin.Forms werden referenzierte Assemblys nach XmlnsDefinitionAttribute Instanzen durchsucht. Wenn das xmlns Attribut für ein Element in einer XAML-Datei dem XmlNamespace Eigenschaftswert in einer XAML-Datei XmlnsDefinitionAttributeentspricht, wird versucht, Xamarin.Forms den Eigenschaftswert für die XmlnsDefinitionAttribute.ClrNamespace Auflösung des Typs zu verwenden. Wenn die Typauflösung fehlschlägt, wird weiterhin versucht, Xamarin.Forms die Typauflösung basierend auf allen zusätzlichen übereinstimmenden XmlnsDefinitionAttribute Instanzen zu versuchen.

Das Ergebnis ist, dass zwei CircleButton-Instanzen angezeigt werden:

Kreisschaltflächen