XAML-Schemas für benutzerdefinierte Namespaces 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 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: