XAML-Namespaces und Namespacezuordnung für WPF-XAML

Diesem Thema bietet weitere Erläuterungen zu Vorhandensein und Zweck der beiden XAML-Namespacezuordnungen, die häufig im Stammelement einer WPF XAML-Datei zu finden sind. Es wird ebenfalls beschrieben, wie Sie ähnliche Zuordnungen für Elemente in Ihrem eigenen Code und/oder separaten Assemblys erstellen können.

Was ist ein XAML-Namespace?

Ein XAML-Namespace ist eine Erweiterung des Konzepts eines XML-Namespaces. Die Techniken zum Angeben eines XAML-Namespaces basieren auf der XML-Namespace-Syntax, der Konvention für die Verwendung von URIs als Namespacebezeichner, der Verwendung von Präfixen als Mittel zur Referenzierung mehrerer Namespaces aus derselben Markupquelle und so weiter. Das primäre Konzept, das der XAML-Definition des XML-Namespaces hinzugefügt wird, ist, dass ein XAML-Namespace einen eindeutigen Bereich für Markupverwendungen schafft und außerdem beeinflusst, wie Markupentitäten potenziell von bestimmten CLR-Namespaces und referenzierten Assemblys unterstützt wird. Letzteres wird auch durch das Konzept eines XAML-Schemakontexts beeinflusst. Was die Funktionsweise von WPF mit XAML-Namespaces angeht, reicht es jedoch, von XAML-Namespaces als die Kombination aus einem standardmäßigen XAML-Namespace, dem XAML-Sprachnamespace und weiteren, für die direkte Zuordnung von XAML-Markup zu bestimmten unterstützenden CLR-Namespaces und referenzierten Assemblys XAML-Namespaces verwendeten XAML-Namespaces zu reden.

Deklarationen der WPF- und XAML-Namespaces

Innerhalb der Namespacedeklarationen im Stammelement vieler XAML-Dateien sehen Sie, dass in der Regel zwei XML-Namespacedeklarationen vorhanden sind. Die erste Deklaration ordnet den gesamten WPF-Client/Framework-XAML-Namespace als Standard zu:

xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"

Die zweite Deklaration ordnet einen separaten XAML-Namespace (normalerweise) dem x:-Präfix zu.

xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"

Die Beziehung zwischen diesen beiden Deklaration ist, dass die x:-Präfix-Zuordnung die in der XAML-Sprache definierten Basiselemente auszeichnet, während WPF eine Implementierung ist, die XAML als Sprache nutzt und ein Vokabular seiner eigenen Objekte für XAML definiert. Da die Verwendung von WPF-Vokabular weitaus häufiger als die Verwendung von XAML-Interna sein wird, wird das WPF-Vokabular als Standard zugeordnet.

Nach der x:-Präfix-Konvention für die Zuordnung der Unterstützung für die systeminternen Funktionen der XAML-Sprache folgen Projektvorlagen, Beispielcode und die Dokumentation der Sprachfeatures in diesem SDK. Der XAML-Namespace definiert viele häufig verwendete Funktionen, die auch für einfache WPF-Anwendung erforderlich sind. Um beispielsweise CodeBehind mittels einer partiellen Klasse zu einer XAML-Datei hinzuzufügen, müssen Sie diese Klasse als x:Class-Attribut im Stammelement der relevanten XAML-Datei benennen. Genauer: Sie müssen für jedes in einer XAML-Seite definierte Element, auf das Sie als mit einem Schlüssel versehene Ressource zugreifen möchten, ein entsprechendes x:Key-Attribut setzen. Weitere Informationen zu diesen und anderen Aspekten von XAML finden Sie unter XAML in WPF oder Ausführliche Erläuterung der XAML-Syntax.

Zuordnen von Benutzerdefinierten Klassen und Assemblys

Sie können XML-Namespaces bestimmten Assemblys mittels einer Reihe von Token mit xmlns-Präfixdeklaration zuordnen, ähnlich wie die standardmäßigen WPF- und XAML-Interna Präfixen im XAML-Namespace zugeordnet sind.

Die Syntax akzeptiert die folgenden möglichen benannten Token und die folgenden Werte:

clr-namespace: Der CLR-Namespace, der innerhalb der Assembly deklariert ist, die die öffentlichen Typen enthält, welche als Elemente verfügbar gemacht werden sollen.

assembly=: Die Assembly, die einige oder alle der CLR-Namespaces enthält, auf die verwiesen wird. Dieser Wert ist in der Regel nur der Name der Assembly, nicht der Pfad zu ihr, und er schließt nicht die Erweiterung (z.B. .dll oder .exe) ein. Der Pfad zu dieser Assembly muss als Projektreferenz in der Projektdatei hergestellt werden, die das zuzuordnende XAML enthält. Um Versionsverwaltung und Signaturen mit starkem Namen einzubeziehen, kann der Wert assembly eine Zeichenfolge sein, wie sie durch AssemblyName definiert ist, anstatt der einfache Zeichenfolgenname.

Beachten Sie, dass als Trennzeichen zwischen clr-namespace-Token und dessen Wert ein Doppelpunkt (:) verwendet wird, während der assembly-Token von seinem Wert mit einem Gleichheitszeichen (=) getrennt ist. Das zwischen diesen beiden Token zu verwendende Zeichen ist ein Semikolon. Darüber hinaus dürfen an keiner Stelle der Deklaration Leerzeichen verwendet werden.

Ein Beispiel für einfache benutzerdefinierte Zuordnung

Der folgende Code definiert eine benutzerdefinierte Beispielklasse:

namespace SDKSample {  
    public class ExampleClass : ContentControl {  
        public ExampleClass() {  
        ...  
        }  
    }  
}  
Namespace SDKSample  
    Public Class ExampleClass  
        Inherits ContentControl  
         ...  
        Public Sub New()  
        End Sub  
    End Class  
End Namespace  

Diese benutzerdefinierte Klasse wird dann in eine Bibliothek kompiliert, die gemäß den (nicht dargestellten) Projekteinstellungen SDKSampleLibrary heißt.

Um auf diese benutzerdefinierte Klasse zu verweisen, müssen Sie diese auch als Verweis für das aktuelle Projekt hinzufügen. Dazu nutzen Sie in der Regel die Projektmappen-Explorer-Benutzeroberfläche in Visual Studio.

Nun, da Sie eine Bibliothek mit einer Klasse und einen Verweis darauf in den Projekteinstellungen haben, können Sie die folgende Präfix-Zuordnung als Teil des XAML-Stammelements hinzufügen:

xmlns:custom="clr-namespace:SDKSample;assembly=SDKSampleLibrary"

Zusammenfassend sehen Sie im Folgenden den XAML-Code mit der benutzerdefinierten Zuordnung, zusammen mit den herkömmlichen Zuordnungen und den x:-Zuordnungen im Stammelement, der dann einen Verweis mittels Präfix verwendet, um ExampleClass in der Benutzeroberfläche zu instanziieren:

<Page x:Class="WPFApplication1.MainPage"  
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"  
    xmlns:custom="clr-namespace:SDKSample;assembly=SDKSampleLibrary">  
  ...  
  <custom:ExampleClass/>  
...  
</Page>  

Zuordnen von aktuellen Assemblys

assembly kann ausgelassen werden, wenn die referenzierte clr-namespace innerhalb der gleichen Assembly wie der Anwendungscode definiert ist, der auf die benutzerdefinierten Klassen verweist. Eine alternative Syntax für diesen Fall ist die Angabe assembly=, ohne Zeichenfolgetoken nach dem Gleichheitszeichen.

Benutzerdefinierte Klassen können nicht als Stammelement einer Seite verwendet werden, wenn sie in der gleichen Assembly definiert sind. Partielle Klassen müssen nicht zugeordnet werden. Es müssen nur Klassen zugeordnet werden, die keine partielle Klasse einer Seite in Ihrer Anwendung sind, wenn Sie auf diese als Elemente in XAML verweisen möchten.

Zuordnen von CLR-Namespaces zu XML-Namespaces in einer Assembly

WPF definiert ein CLR-Attribut, das von XAML-Prozessoren verwendet wird, um mehrere CLR-Namespaces einem einzigen XAML-Namespace zuzuordnen. Dieses XmlnsDefinitionAttribute-Attribut befindet sich auf der Assemblyebene in dem Quellcode, der die Assembly generiert. Der Quellcode der WPF-Assembly verwendet dieses Attribut, um die verschiedenen allgemeinen Namespaces wie z. B. System.Windows.Controls und http://schemas.microsoft.com/winfx/2006/xaml/presentation dem System.Windows-Namespace zuzuordnen.

XmlnsDefinitionAttribute nimmt zwei Parameter an: den XML/XAML-Namespacenamen und den CLR-Namespacenamen. Es können mehrere XmlnsDefinitionAttribute-Elemente vorhanden sein, um mehrere CLR-Namespaces demselben XML-Namespace zuzuordnen. Sind diese einmal zugeordnet, kann in der CodeBehind-Seite der partiellen Klasse auf Mitglieder dieser Namespaces auf Wunsch auch ohne vollqualifizierten Bezeichner durch Angabe des entsprechenden using-Statements verwiesen werden. Weitere Details finden Sie unter XmlnsDefinitionAttribute.

Designer-Namespaces und andere Präfixe aus XAML-Vorlagen

Wenn Sie mit Entwicklungsumgebungen und/oder Entwurfstools für WPF-XAML arbeiten, werden Sie bemerken, dass es im XAML-Markup weitere definierte XAML-Namespaces/Präfixe gibt.

WPF-Designer für Visual Studio verwendet einen Designer-Namespace, der üblicherweise dem Präfix d: zugeordnet ist. Neuere Projektvorlagen für WPF ordnen dieses Präfix möglicherweise bereits im Vorfeld zu, um den Austausch von XAML zwischen WPF-Designer für Visual Studio und andere Entwurfsumgebungen zu unterstützen. Dieser XAML-Designer-Namespace wird verwendet, um bei Roundtrips von XAML-basierten Benutzeroberflächen den jeweiligen Stand des Designs festzuhalten. Er wird ebenfalls für Funktionen wie z.B. d:IsDataSource verwendet, die die Laufzeit-Datenquellen in einem Designer aktivieren.

Ein anderes Präfix, dessen Zuordnung Sie möglicherweise sehen können, ist mc:. mc: dient der Markupkompatibilität. Dabei wird ein Markup-Kompatibilitätsmuster wiederverwendet, das nicht unbedingt XAML-spezifisch ist. In gewissem Umfang können die Markupkompatibilitäts-Funktionen verwendet werden, um XAML zwischen Frameworks oder grenzübergreifend mit unterstützenden Implementierungen auszutauschen, zwischen verschiedenen XAML-Schema-Kontexten zu arbeiten, Kompatibilität für eingeschränkte Modi in Designern bereitzustellen, und so weiter. Weitere Informationen zu Markupkompatibilitätskonzepten und deren Bezug auf WPF finden Sie unter Markupkompatibilität (mc:) – Sprachfeatures.

WPF und Laden von Assemblys

Der XAML-Schemakontext für WPF ist in das WPF-Anwendungsmodell integriert, das wiederum das von CLR definierte Konzept von AppDomain verwendet. Die folgende Sequenz beschreibt, wie der XAML-Schemakontext basierend auf der WPF-Verwendung von AppDomain und anderen Faktoren entscheidet, ob Assemblys zu laden sind, oder ob Typen während Laufzeit oder Entwurfszeit zu suchen sind.

  1. Durchlaufe die AppDomain, um nach einer bereits geladenen Assembly zu suchen, die mit allen Aspekten des Namens übereinstimmt, beginnend mit der zuletzt geladenen Assembly.

  2. Wenn der Name qualifiziert ist, rufe Assembly.Load(String) für den qualifizierten Namen auf.

  3. Wenn der Kurzname und das öffentliche Schlüsseltoken eines qualifizierten Namens mit der Assembly übereinstimmen, aus der das Markup geladen wurde, gib diese Assembly zurück.

  4. Verwende den Kurznamen und das öffentliche Schlüssel, um Assembly.Load(String) aufzurufen.

  5. Wenn der Name nicht qualifiziert ist, rufe Assembly.LoadWithPartialName auf.

Loose XAML verwendet Schritt 3 nicht, da es nicht aus Assemblys geladen wird.

Kompiliertes XAML für WPF (mithilfe XamlBuildTask generiert) verwendet nicht die bereits geladenen Assemblys aus AppDomain (Schritt 1). Darüber hinaus sollte der aus XamlBuildTask resultierende Name nie unqualifiziert sein, weshalb Schritt 5 hier nicht anwendbar ist.

Kompiliertes BAML (mit PresentationBuildTask generiert) verwendet alle Schritte, obwohl auch BAML keine unqualifizierten Assemblynamen enthalten sollte.

Weitere Informationen