Freigeben über


Markuperweiterungen und XAML

Aktualisiert: November 2007

Dieses Thema ist eine Einführung in das Konzept der Markuperweiterungen für Extensible Application Markup Language (XAML) mit Erläuterung der Syntaxregeln, des Zwecks und des zugrunde liegenden Klassenobjektmodells.

Dieses Thema enthält folgende Abschnitte.

  • XAML-Prozessoren und Markuperweiterungen
  • Grundlegende Markuperweiterungssyntax
  • WPF-spezifische Markuperweiterungen
  • XAML-definierte Markuperweiterungen
  • Weitere Informationen zu Markuperweiterungssyntax
  • Verwandte Abschnitte

XAML-Prozessoren und Markuperweiterungen

Als XAML-Prozessor wird ein Programm definiert, das XAML gemäß der entsprechenden Spezifikationen als Sprache akzeptiert (durch Kompilierung oder durch Interpretation), und das die zugrunde liegenden Klassen zur Verwendung durch ein Laufzeitobjektmodell produzieren kann (ebenfalls gemäß der XAML-Spezifikationen). Standardmäßig werden Attributwerte durch einen solchen Prozessor als Zeichenfolgenliteral interpretiert oder auf der Basis des Attributtyps bzw. der Typkonverter des Attributs in ein Objekt konvertiert. In einigen Szenarios ist jedoch ein anderes Verhalten erforderlich. Ein XAML-Prozessor kann z. B. angewiesen werden, dass der Wert eines Attributs ein Verweis auf ein bereits erstelltes Objekt oder ein statisches Objekt sein soll. Des Weiteren kann ein XAML-Prozessor angewiesen werden, eine Syntax zu verwenden, die Nicht-Standardargumente für den Konstruktor eines Objekts bereitstellt, wobei es sich um eine Abweichung vom standardmäßigen XAML-Prozessorverhalten handelt.

Grundlegende Markuperweiterungssyntax

Eine Markuperweiterung kann implementiert werden, um Werte für Eigenschaften bei Verwendung von Attributen oder Eigenschaften bei Verwendung von Eigenschaftenelementen bereitzustellen oder beides.

Bei Verwendung der Markuperweiterung zur Bereitstellung eines Attributwerts wird diese durch öffnende und schließende geschweifte Klammern ({ und }) für den XAML-Prozessor kenntlich gemacht. Der Typ der Markuperweiterung wird durch das Zeichenfolgentoken angegeben, das unmittelbar auf die öffnende geschweifte Klammer folgt.

Bei Verwendung in Eigenschaftenelementsyntax entspricht das Erscheinungsbild der Markuperweiterung einem Element, das zur Bereitstellung eines Eigenschaftenelementwerts verwendet wird: eine XAML-Elementdeklaration, die auf die Markuperweiterungsklasse als Element verweist und von spitzen Klammern (<>) umschlossen ist.

WPF-spezifische Markuperweiterungen

Die bei der WPF-Programmierung am häufigsten verwendeten Markuperweiterungen sind die, die Ressourcenverweise unterstützen (StaticResource und DynamicResource), und die, die Datenbindungen unterstützen (Binding).

StaticResource stellt einen Wert für eine XAML-Eigenschaft bereit, indem der Wert einer bereits definierten Ressource verwendet wird. Nähere Informationen finden Sie unter StaticResource-Markuperweiterung.

DynamicResource stellt einen Wert für eine XAML-Eigenschaft bereit, indem zur Laufzeit auf eine Ressource verwiesen wird. Durch einen dynamischen Ressourcenverweis wird bei jedem Zugriff auf die Ressource eine neue Suche erzwungen. Nähere Informationen finden Sie unter DynamicResource-Markuperweiterung.

Binding stellt gemäß dem Datenkontext des Elements einen datengebundenen Wert für eine Eigenschaft bereit. Diese Markuperweiterung ist relativ komplex, da sie eine komplexe Inlinesyntax für die Angabe einer Datenbindung aktiviert. Nähere Informationen finden Sie unter Bindung als Markuperweiterung.

RelativeSource stellt Quellinformationen für eine Binding bereit, wobei in der Laufzeitelementstruktur durch mehrere mögliche Beziehungen navigiert werden kann. Hierdurch werden spezielle Quellbezüge für Bindungen bereitgestellt, die in Mehrzweckvorlagen oder in Code ohne vollständige Kenntnis der umgebenden Elementstruktur erstellt wurden. Nähere Informationen finden Sie unter RelativeSource-Markuperweiterung.

TemplateBinding ermöglicht die Verwendung von Eigenschaftenwerten in Steuerelementvorlagen, die von den durch das Objektmodell definierten Eigenschaften der Klasse abgeleitet werden, die die Vorlage verwenden werden. Nähere Informationen finden Sie unter TemplateBinding-Markuperweiterung. Weitere Informationen über die praktische Verwendung von TemplateBinding finden Sie unter Beispiel zum Formatieren mit ControlTemplates.

XAML-definierte Markuperweiterungen

Es gibt mehrere Markuperweiterungen, die nicht spezifisch für die WPF-Anwendung von XAML, sondern Teil der Spezifikation und des Namespace von XAML als Sprache sind. Diese sind in der Regel durch das x:-Präfix in der Syntax identifizierbar. Die WPF-Implementierung für diese Sprachelemente verwendet dieselbe MarkupExtension-Basisklasse, um die Implementierung bereitzustellen.

Tipp

Das x:-Präfix wird für die typische XML-Namespace-Zuordnung des XAML-Namespace im Stammelement einer XAML-Anwendung bzw. eines Dokuments verwendet. Beispiel: Microsoft Visual Studio 2005-Vorlagen initiieren eine XAML-Datei mit dieser x:-Zuordnung. Sie können ein anderes Präfix-Token in Ihrer eigenen XML-Namespace-Zuordnung wählen, in dieser Dokumentation wird jedoch die x:-Standardzuordnung für die Identifizierung der Entitäten vorausgesetzt, die als Teil des XAML-Namespace definiert sind, im Gegensatz zum WPF-Namespace und anderen CLR- oder XML-Namespaces.

x:Type stellt das Type-Objekt für den benannten Typ bereit. Dies wird am häufigsten in Formaten und Vorlagen verwendet. Nähere Informationen finden Sie unter x:Type-Markuperweiterung.

x:Static erstellt statische Werte aus Werttyp-Codeentitäten, die nicht direkt dem Typ eines Eigenschaftenwerts entsprechen, die jedoch diesem Typ entsprechend ausgewertet werden können. Nähere Informationen finden Sie unter x:Statische Markuperweiterung.

x:Null gibt null als Wert für eine XAML-Eigenschaft an. Nähere Informationen finden Sie unter x:Null-Markuperweiterung.

x:Array bietet Unterstützung für die Erstellung von allgemeinen Arrays in XAML-Syntax, wenn die Auflistungsunterstützung von Basiselementen und Steuerelementmodellen nicht verwendet wird. Nähere Informationen finden Sie unter x:Array-Markuperweiterung.

Weitere Informationen zu Markuperweiterungssyntax

*Erweiterungsklassen

Das Verhalten der einzelnen Markuperweiterungen wird für einen XAML-Prozessor über eine *Erweiterungsklasse identifiziert, die von MarkupExtension abgeleitet wird und eine Implementierung der ProvideValue-Methode bereitstellt. Diese Methode definiert für jede Erweiterung, welches Objekt bei Auswertung der Markuperweiterung zurückgegeben wird. Das zurückgegebene Objekt wird in der Regel instanziiert oder mithilfe der verschiedenen an die Markuperweiterung übergebenen Zeichenfolgentoken festgelegt.

Beispiel: Die StaticResourceExtension-Klasse stellt die Oberflächenimplementierung der tatsächlichen Ressourcensuche bereit, sodass die zugehörige ProvideValue-Implementierung das angeforderte Objekt zurückgibt, wobei die Eingabe dieser Implementierung eine Zeichenfolge ist, die für die Suche nach der Ressource anhand des zugehörigen x:Key verwendet wird. Ein großer Teil dieser Implementierungsdetails ist nicht von Bedeutung, wenn Sie eine vorhandene Markuperweiterung verwenden.

Erweiterungsklasse – Interpretation der folgenden Zeichenfolgentoken

Die Zeichenfolgentoken, die auf den Bezeichner der Markuperweiterung folgen und sich innerhalb der Klammern befinden, werden von einem XAML-Prozessor auf eine der folgenden Arten interpretiert:

  • Ein Komma fungiert immer als Trennzeichen einzelner Token. Aus diesem Grund kann ein Komma nicht als Literalzeichen an eine Markuperweiterung übergeben werden.

  • Wenn die einzelnen getrennten Token keine Gleichheitszeichen enthalten, wird jedes Token als Konstruktorargument behandelt. Jeder Konstruktorparameter muss als Typ angegeben werden, der von der Signatur erwartet wird, und die Angabe muss in der von der Signatur erwarteten Reihenfolge erfolgen.

    Tipp

    Ein XAML-Prozessor muss den Konstruktor aufrufen, der der Argumentanzahl der Anzahl von Paaren entspricht. Wenn Sie eine benutzerdefinierte Markuperweiterung implementieren, dürfen Sie aus diesem Grund nicht mehrere Parameter mit derselben Argumentanzahl bereitstellen, da für mehrere Markuperweiterungskonstruktoren mit derselben Parameteranzahl kein Verhalten definiert ist.

  • Wenn die einzelnen Token Gleichheitszeichen enthalten, ruft der XAML-Prozessor zuerst den Standardkonstruktor für die Markuperweiterung auf. Dann wird jedes Name=Wert-Paar als in der Markuperweiterung vorhandener Eigenschaftenname und als Wert interpretiert, der der Eigenschaft zuzuweisen ist.

  • Wenn in einer Markuperweiterung ein paralleles Ergebnis zwischen dem Konstruktorverhalten und dem Verhalten der Eigenschafteneinstellung vorliegt, können Sie zwischen den Verhalten wählen. Die Verwendung von Eigenschaft=Wert-Paaren mit mehreren festlegbaren Eigenschaften für Markuperweiterungen ist gängiger, da hierbei ein geringeres Risiko besteht, Konstruktorparameter versehentlich zu vertauschen (bei der Angabe von Eigenschaft=Wert-Paaren spielt die Reihenfolge der Eigenschaften keine Rolle). Des Weiteren ist nicht garantiert, dass eine Markuperweiterung einen Konstruktorparameter angibt, der alle festlegbaren Eigenschaften festlegt. Beispiel: Binding ist eine Markuperweiterung mit vielen Eigenschaften, die durch die Erweiterung in der Form Eigenschaft=Wert festlegbar sind, Binding unterstützt jedoch nur zwei Konstruktoren: einen Standardkonstruktor und einen Konstruktor, der einen Anfangspfad festlegt.

Escapezeichen für literale geschweifte Klammern

Bei der Attributbehandlung in einem XAML-Prozessor werden geschweifte Klammern als Bezeichner für Markuperweiterungen verwendet. Falls erforderlich, können Sie geschweifte Klammern als Literalzeichen angeben, indem Sie eine Escapesequenz in Form eines leeren Paars geschweifter Klammern gefolgt von der literalen geschweiften Klammer angeben. Informationen hierzu finden Sie unter {}-Escapesequenz/Markuperweiterung.

Schachteln von Erweiterungssyntax

Die Schachtelung mehrerer Markuperweiterungen wird unterstützt, wobei die einzelnen Markuperweiterungen beginnend mit der tiefsten Ebene ausgewertet werden. Beispiel:

<Setter Property="Background"

Value="{DynamicResource {x:Static SystemColors.ControlBrushKey}}" />

Weitere Informationen zu Markuperweiterungen und Eigenschaftenelementsyntax

Bei Verwendung einer Markuperweiterungsklasse als Objektelement, das in einen Eigenschaftenelementwert geladen wird, ist diese visuell nicht von regulären Elementen zu unterscheiden, die in XAML verwendet werden können. In diesem Fall besteht der praktische Unterschied zwischen einem regulären Element und einer Markuperweiterung darin, dass die Markuperweiterung entweder als typisierter Wert ausgewertet oder als Ausdruck verzögert wird. Aus diesem Grund ist der Mechanismus für mögliche Typfehler bei Eigenschaftenwerten unterschiedlich, ähnlich wie die Behandlung einer Eigenschaft mit später Bindung in anderen Programmiermodellen. Ein reguläres Element wird als Typ ausgewertet, während die Eigenschaft unmittelbar bei der Kompilierung festgelegt wird.

Bei Verwendung in Objektelementsyntax, die in ein Eigenschaftenelement geladen wird, enthalten die meisten Markuperweiterungen keinen Inhalt oder weitere Eigenschaftenelementsyntax, sodass Sie das Objektelementtag schließen und keine untergeordneten Elemente bereitstellen würden. Wenn ein Objektelement von einem XAML-Prozessor erkannt wird, wird der Konstruktor für diese Klasse aufgerufen, um das aus dem geparsten Element erstellte Objekt zu instanziieren. Dies gilt auch für Markuperweiterungsklassen. Wenn Sie also die Markuperweiterung in Objektelementsyntax verwenden möchten, müssen Sie einen Standardkonstruktor angeben. Einige vorhandene Markuperweiterungen verfügen über mindestens einen erforderlichen Eigenschaftenwert, der für eine erfolgreiche Initialisierung angegeben werden muss. In diesem Fall wird der Eigenschaftenwert in der Regel als Eigenschaftenattribut des Objektelements angegeben. Markuperweiterungen mit erforderlichen Eigenschaften (sowie die Namen dieser Eigenschaften) werden auf den Referenzseiten Sprachfeatures des XAML-Namespace (x:) und XAML-definierte WPF-Namespaceerweiterungen aufgeführt. Des Weiteren wird auf den Referenzseiten darauf hingewiesen, wenn Objektelementsyntax oder Attributsyntax von einer Markuperweiterung nicht unterstützt werden. Ein wichtiger Fall ist x:Array-Markuperweiterung, die Attributsyntax nicht unterstützt, da der Inhalt des Arrays angegeben werden muss. Die Arrayinhalte werden als allgemeine Objekte behandelt, sodass kein Standardtypkonverter für das Attribut zulässig ist. Außerdem erfordert x:Array-Markuperweiterung einen Type-Parameter.

Siehe auch

Konzepte

Übersicht über XAML

Referenz

StaticResource-Markuperweiterung

Bindung als Markuperweiterung

DynamicResource-Markuperweiterung

x:Type-Markuperweiterung

Weitere Ressourcen

Sprachfeatures des XAML-Namespace (x:)

XAML-definierte WPF-Namespaceerweiterungen