XAML-Schemas für benutzerdefinierte Namespaces in Xamarin.Forms

Beispiel herunterladen Das Beispiel herunterladen

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

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

Die Angabe eines CLR-Namespaces 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 besteht darin, ein benutzerdefiniertes Namespaceschema zu definieren, z http://mycompany.com/schemas/controls. B. , das einem oder mehreren CLR-Namespaces zugeordnet ist. Dadurch kann eine einzelne XAML-Namespacedeklaration auf alle Typen in einer Assembly verweisen, auch wenn sie sich in unterschiedlichen 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 verfügbar macht, z. B CircleButton.:

using Xamarin.Forms;

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

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

Mit der XmlnsDefinitionAttribute -Klasse wird ein benutzerdefiniertes Namespaceschema definiert, das die Zuordnung zwischen einem XAML-Namespace und mindestens einem CLR-Namespace angibt. Die XmlnsDefinitionAttribute verwendet zwei Argumente: den XAML-Namespacenamen und den CLR-Namespacenamen. Der XAML-Namespacename wird in der XmlnsDefinitionAttribute.XmlNamespace -Eigenschaft und der CLR-Namespacename in der XmlnsDefinitionAttribute.ClrNamespace -Eigenschaft gespeichert.

Hinweis

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

Sollte XmlnsDefinitionAttribute auf Assemblyebene im Projekt definiert werden, das die CLR-Namespaces enthält, die im schema des benutzerdefinierten Namespaces zugeordnet werden. Das folgende Beispiel zeigt die Datei AssemblyInfo.cs 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 http://mycompany.com/schemas/controls URL dem MyCompany.Controls CLR-Namespace zuordnet. Darüber hinaus wird das Preserve Attribut für die Assembly angegeben, um sicherzustellen, dass der Linker alle Typen in der Assembly behält.

Wichtig

Das Preserve Attribut sollte auf Klassen in der Assembly angewendet werden, die über das schema des benutzerdefinierten Namespaces zugeordnet oder auf die gesamte Assembly angewendet werden.

Das schema des benutzerdefinierten Namespaces kann dann für die Typauflösung in XAML-Dateien verwendet werden.

Verwenden eines benutzerdefinierten Namespaceschemas

Um Typen aus dem benutzerdefinierten Namespaceschema zu nutzen, erfordert der XAML-Compiler, dass es einen Codeverweis von der Assembly gibt, die die Typen nutzt, auf die Assembly, die die Typen definiert. Dies kann erreicht werden, indem Sie der Assembly eine -Klasse mit einer Init -Methode hinzufügen, die die Typen definiert, die über XAML verwendet werden:

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 schema des benutzerdefinierten Namespaces verwendet:

using Xamarin.Forms;
using MyCompany.Controls;

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

Warnung

Fehler beim Einschließen eines solchen Codeverweiss führen dazu, dass der XAML-Compiler die Assembly, die die Schematypen des benutzerdefinierten Namespaces enthält, nicht finden kann.

Um das CircleButton Steuerelement zu nutzen, wird ein XAML-Namespace deklariert, wobei die Namespacedeklaration die SCHEMA-URL des benutzerdefinierten Namespaces 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 dem hinzugefügt werden, ContentPage indem Sie sie mit dem controls Namespacepräfix deklarieren.

Um die schematypen des benutzerdefinierten Namespaces zu finden, durchsucht assemblys, auf die verwiesen wird, Xamarin.Forms nach XmlnsDefinitionAttribute Instanzen. Wenn das xmlns Attribut für ein Element in einer XAML-Datei mit dem XmlNamespace Eigenschaftswert in einem XmlnsDefinitionAttributeübereinstimmt, 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