Terminologie der XAML-Syntax
Aktualisiert: November 2007
In diesem Thema werden die Begriffe definiert, die zur Beschreibung der Extensible Application Markup Language (XAML)-Syntaxelemente verwendet werden. Diese Begriffe werden in diesem Software Development Kit (SDK) häufig verwendet. Dieses Thema baut auf der im Thema Übersicht über XAML eingeführten grundlegenden Terminologie auf.
Dieses Thema enthält folgende Abschnitte.
- Ursprung der XAML-Syntaxterminologie
- Objektelementsyntax
- Attributsyntax
- Eigenschaftenelementsyntax
- XAML-Inhaltssyntax
- Angefügte Eigenschaften
- Angefügte Ereignisse
- XML-Namespaces
- Markuperweiterungen
- Optionale und nicht zu empfehlende Verwendungen von XAML
- Verwandte Abschnitte
Ursprung der XAML-Syntaxterminologie
Die hier definierte Terminologie der XAML-Syntax ist auch in der XAML-Sprachspezifikation definiert, bzw. es wird darauf verwiesen. XAML basiert auf XML und XML-Strukturregeln. Einige Begriffe basieren auf der Terminologie, die häufig zur Beschreibung der XML-Sprache oder des XML-Dokumentobjektmodell (DOM) verwendet wird.
Objektelementsyntax
Objektelementsyntax ist die XAML-Markupsyntax, die eine common language runtime (CLR)-Klasse oder -Struktur durch Deklarieren eines XML-Elements instanziiert. Diese Syntax ähnelt der Elementsyntax von anderen Markupsprachen wie HTML. Die Objektelementsyntax beginnt mit einer öffnenden spitzen Klammer (<) gefolgt von dem Typnamen der Klasse oder Struktur, die instanziiert wird. Dem Typnamen können 0 (null) oder mehr Leerzeichen folgen, und im Objektelement können 0 (null) oder mehr Attribute deklariert werden, wobei die einzelnen attribute name="Wert"-Paare durch ein oder mehrere Leerzeichen getrennt werden müssen. Außerdem muss eine der folgen Aussagen zutreffen:
Element und Tag müssen durch einen Schrägstrich (/) und eine unmittelbar darauf folgende schließende spitze Klammer (>) geschlossen werden.
Das Starttag muss durch eine schließende spitze Klammer (>) vervollständigt werden. Dem Starttag können andere Objektelemente, Eigenschaftenelemente oder innerer Text folgen. Welche Inhalte genau zugelassen sind, wird durch das Objektmodell des Elements festgelegt. Weitere Informationen hierzu finden Sie unter "Inhaltssyntax" in diesem Thema. Das entsprechende schließende Tag für das Objektelement muss ebenfalls vorhanden und richtig verschachtelt bzw. mit den anderen Tag-Paaren abgestimmt sein.
Das folgende Beispiel zeigt eine Objektelementsyntax, die eine neue Instanz der Button-Klasse instanziiert sowie ein Name-Attribut und einen Wert für dieses Attribut angibt:
<Button Name="CheckoutButton"/>
Das folgende Beispiel zeigt eine Objektelementsyntax, die auch Eigenschaftensyntax des Extensible Application Markup Language (XAML)-Inhalts umfasst. Der darin enthaltene innere Text wird verwendet, um den Wert für die TextBox-Extensible Application Markup Language (XAML)-Inhaltseigenschaft festzulegen, Text.
<TextBox>This is a Text Box</TextBox>
Attributsyntax
Attributsyntax ist die XAML-Markupsyntax, die durch Deklarieren eines Attributs in einem Element einen Wert für eine Eigenschaft festlegt oder einen Ereignishandler für ein Ereignis benennt. Das Element wird immer durch Objektelementsyntax deklariert. Der Attributname muss dem CLR-Membernamen entweder einer Eigenschaft oder eines Ereignisses entsprechen. Dem Attributnamen folgt ein Zuweisungsoperator (=). Der Attributwert muss eine in doppelte Anführungszeichen (") eingeschlossene Zeichenfolge sein.
Um mithilfe von Attributsyntax festgelegt werden zu können, muss eine Eigenschaft öffentlich sein, über Lese- und Schreibzugriff verfügen und einen Eigenschaftenwerttyp aufweisen, der instanziiert werden kann bzw. auf den ein XAML-Prozessor verweisen kann. Ereignisse müssen öffentlich sein und über einen öffentlichen Delegaten verfügen. Die Eigenschaft/das Ereignis muss ein Member der Klasse oder Struktur sein, die von dem Container-Objektelement instanziiert wird.
Der Attributwert wird durch eine der folgenden Möglichkeiten mit Daten geladen, wobei die folgende Verarbeitungsreihenfolge gilt:
Wenn der XAML-Prozessor auf eine geschweifte Klammer oder ein von MarkupExtension abgeleitetes Objektelement trifft, wird statt der Verarbeitung als Zeichenfolge zunächst die Markuperweiterung ausgewertet, auf die verwiesen wird, und das von der Markuperweiterung zurückgegebene Objekt wird verwendet. In vielen Fällen ist das von der Markuperweiterung zurückgegebene Objekt kein neues Objekt, sondern ein Verweis auf ein vorhandenes Objekt oder ein Ausdruck, der die Auswertung bis zur Laufzeit zurückstellt.
Bei Deklaration der Eigenschaft mit einem festgelegten TypeConverter oder bei Deklaration des Eigenschaftenwerttyps mit einem attributierten TypeConverter wird der Zeichenfolgenwert des Attributs als Konvertierungseingabe an den Typkonverter übergeben, und der Konverter gibt eine neue Objektinstanz zurück.
Wenn kein TypeConverter angegeben wurde, wird versucht, eine direkte Konvertierung in den Eigenschaftentyp durchzuführen. Bei dieser letzten Ebene handelt es sich um eine direkte Konvertierung zwischen primitiven Typen oder um eine Überprüfung auf Namen in einer Enumeration, wobei die übereinstimmenden Werte zurückgegeben werden.
Das folgende Beispiel zeigt die Attributsyntax, mit der ein Zeichenfolgenwert für die Name-Eigenschaft zugewiesen wird (unter Verwendung desselben Markups wie zuvor gezeigt):
<Button Name="CheckoutButton"/>
Die Name-Eigenschaft ist ein Member der Membertabelle für die Button-Klasse. Button ist eine abgeleitete Klasse der FrameworkElement-Klasse, die Name definiert.
Verarbeiten von Attributwerten
Der von Anführungszeichen umschlossene Zeichenfolgenwert wird von einem XAML-Prozessor verarbeitet. Für Eigenschaften wird das Standardverarbeitungsverhalten anhand des Typs der zugrunde liegenden CLR-Eigenschaft festgelegt. Wenn es sich bei der Eigenschaft um einen primitiven Typ handelt, wird der Attributwert auf Basis der impliziten Konvertierung der Zeichenfolge in den entsprechenden primitiven Typ zugewiesen. Wenn die Eigenschaft eine Enumeration darstellt, wird die Zeichenfolge als mit dieser Enumeration definierter Name behandelt, und der übereinstimmende Wert der Enumeration wird zurückgegeben. Wenn es sich weder um einen primitiven Typ noch um eine Enumeration handelt, muss der Attributwert von einem Typkonverter verarbeitet werden, der entweder in der Eigenschaft selbst oder im Zieltyp deklariert wird. Der Typkonverter muss eine Konvertierung bereitstellen, die Zeichenfolgen akzeptiert, und das Ergebnis muss eine Instanz des Typs der zugrunde liegenden CLR-Eigenschaft sein. Der Konvertierungsschritt kann auch durch eine Markuperweiterung zurückgestellt werden.
Enumerationsattributwerte
Enumerationswerte in XAML werden von den Methoden der Enum-Struktur verarbeitet.
Bei Nicht-Flag-Enumerationen wird die Zeichenfolge eines Attributwerts verarbeitet und in einen der Enumerationswerte aufgelöst. Sie geben die Enumeration nicht im Format Enumeration.Wert an wie in Code. Stattdessen geben Sie nur Wert an, und Enumeration wird von dem Eigenschaftstyp, den Sie festlegen, abgeleitet. Wenn Sie ein Attribut im Format Enumeration.Wert angeben, kann es nicht ordnungsgemäß aufgelöst werden.
Bei Flag-Enumerationen basiert das Verhalten auf der Enum.Parse-Methode. Sie können mehrere Werte für eine Flag-Enumeration angeben, indem Sie die einzelnen Werte durch Kommas trennen. Sie können jedoch Enumerationswerte, bei denen es sich nicht um Flag-Enumerationswerte handelt, nicht kombinieren. Beispiel: Es ist nicht möglich, die Kommasyntax zu verwenden, um einen Trigger zu erstellen, der bei mehreren Bedingungen einer Nicht-Flag-Enumeration ausgeführt wird:
<!--This will not compile, because Visibility is not a flagwise enumeration.-->
...
<Trigger Property="Visibility" Value="Collapsed,Hidden">
<Setter ... />
</Trigger>
...
Flag-Enumerationen, die in XAML festlegbare Attribute unterstützen, kommen in WPF nur selten vor. Eine solche Enumeration ist StyleSimulations. Sie können die Flag-Attributsyntax mit Kommas als Trennzeichen beispielsweise verwenden, um das Beispiel in den Hinweisen zur Glyphs-Klasse zu ändern. StyleSimulations = "BoldSimulation" kann z. B. in StyleSimulations = "BoldSimulation,ItalicSimulation" geändert werden. KeyBinding.Modifiers ist eine weitere Eigenschaft, die die Angabe mehrerer Enumerationswerte zulässt. Bei dieser Eigenschaft handelt es sich jedoch um einen Spezialfall, da die ModifierKeys-Enumeration einen eigenen Typkonverter unterstützt. Der Typkonverter für Modifizierer verwendet Pluszeichen (+) statt Kommas (,) als Trennzeichen, sodass die herkömmlichere Syntax zur Darstellung von Tastenkombinationen, wie z. B. "STRG+ALT", im Markup unterstützt wird.
Verweise auf Eigenschafts- und Ereignismembernamen
Bei Angabe eines Attributs können Sie auf beliebige Eigenschaften oder Ereignisse verweisen, die als Member des CLR-Typs enthalten sind, den Sie für das Container-Objektelement instanziiert haben.
Sie können auch unabhängig vom Container-Objektelement auf eine angefügte Eigenschaft bzw. ein angefügtes Ereignis verweisen.
Sie können auch beliebige Ereignisse beliebiger Objekte, die über den Standardnamespace zugänglich sind, mit einem teilweise qualifizierten Namen der Form Typname.Ereignis benennen. Diese Syntax unterstützt das Anfügen von Handlern für Routingereignisse, wobei der Handler zum Routing von Ereignissen untergeordneter Elemente dient, wenn das Ereignis nicht ebenfalls in der Membertabelle des übergeordneten Elements vorhanden ist. Diese Syntax ähnelt einer Syntax mit angefügten Ereignissen, tatsächlich handelt es sich jedoch nicht um ein angefügtes Ereignis. Stattdessen verweisen Sie mit einem qualifizierten Namen auf ein Ereignis. Weitere Informationen finden Sie unter Übersicht über Routingereignisse.
Eigenschaftennamen werden in einigen Fällen statt als Attributname als Attributwert bereitgestellt. Diese Eigenschaftennamen können auch Qualifizierer enthalten, wie z. B. die im Formular ownerType.dependencyPropertyName angegebene Eigenschaft. Dieses Szenario finden Sie häufig beim Schreiben von Stilen oder Vorlagen in XAML. Für als Attributwerte bereitgestellte Eigenschaftennamen gelten andere Verarbeitungsregeln. Außerdem hängen sie vom Typ der festgelegten Eigenschaft und von einigen Kontextfaktoren ab, z. B. davon, ob ein Stil oder eine Vorlage über einen Zieltyp verfügt. Ausführliche Informationen finden Sie unter Erstellen von Formaten und Vorlagen.
Des Weiteren finden Eigenschaftennamen Verwendung, wenn mit einem Attributwert eine Beziehung zwischen zwei Eigenschaften beschrieben wird. Diese Funktion wird für Datenbindungen und Storyboardziele verwendet und mit der PropertyPath-Klasse und dem zugehörigen Typkonverter aktiviert. Eine ausführliche Beschreibung der Suchsemantik finden Sie unter XAML-Syntax von PropertyPath.
Eigenschaftenelementsyntax
Die Eigenschaftenelementsyntax weicht zu einem gewissen Grad von der allgemeinen XML-Syntax ab. In XML ist der Wert eines Attributs eine tatsächliche Zeichenfolge, und die einzige Variationsmöglichkeit ist die Verwendung eines anderen Codierungsformats als UTF-8. In XAML können Sie andere Objektelemente als Eigenschaftenwerte zuweisen. Diese Funktion wird mit der Eigenschaftenelementsyntax aktiviert. Die Eigenschaft wird nicht innerhalb des Elementtags als Attribut, sondern mithilfe eines Startelementtags im Formular elementTypeName.propertyName angegeben. Anschließend wird das Eigenschaftenelement geschlossen.
Die Syntax beginnt mit einer öffnenden spitzen Klammer (<), auf die unmittelbar, d. h. ohne Leerzeichen, der Typname der Klasse oder Struktur folgt, die die Eigenschaftenelementsyntax enthält. Darauf folgt ohne Leerzeichen ein einzelner Punkt (.), dann der Name einer Eigenschaft, die in der Membertabelle des angegebenen Typs vorhanden sein muss, und dann eine schließende spitze Klammer (>). Der Wert, der der Eigenschaft zugewiesen wird, ist im Eigenschaftenelement enthalten. In der Regel wird der Wert als mindestens ein Objektelement angegeben, da es sich bei der Angabe von Objekten als Werte um das Szenario der Eigenschaftenelementsyntax handelt. Zum Schluss muss ein entsprechendes Endtag mit derselben Elementtypname.Eigenschaftenname-Kombination bereitgestellt werden und richtig verschachtelt bzw. mit den anderen Elementtags abgestimmt sein. Das folgende Beispiel zeigt die Eigenschaftenelementsyntax für die ContextMenu-Eigenschaft eines Button.
<Button>
<Button.ContextMenu>
<ContextMenu>
<MenuItem Header="1">First item</MenuItem>
<MenuItem Header="2">Second item</MenuItem>
</ContextMenu>
</Button.ContextMenu>
Right-click me!</Button>
Der Wert innerhalb eines Eigenschaftenelements kann auch als innerer Text angegeben werden, und zwar dann, wenn es sich bei dem angegebenen Eigenschaftentyp um einen primitiven Werttyp, z. B. String, oder eine Enumeration handelt, bei der ein Name angegeben wird. Diese beiden Verwendungsformen sind nicht sehr häufig, da in beiden Fällen auch Attributsyntax unterstützt wird. Ein Beispiel für das Auffüllen eines Eigenschaftenelements mit einer Zeichenfolge sind Eigenschaften, bei denen es sich nicht um die XAML-Inhaltseigenschaft handelt, die aber für Benutzeroberflächen-Text verwendet werden, insbesondere, wenn bestimmte Leerraumelemente wie Zeilenvorschübe in diesem Text erforderlich sind. Im Gegensatz zur Attributsyntax werden Zeilenvorschübe bei der Eigenschaftenelementsyntax beibehalten, vorausgesetzt, wenn die Beibehaltung signifikanter Leerräume aktiviert ist (ausführliche Informationen finden Sie unter Leerstellenverarbeitung in XAML).
Ein Eigenschaftenelement wird nicht in der logischen Struktur dargestellt. Ein Eigenschaftenelement stellt lediglich eine bestimmte Syntax zur Festlegung einer Eigenschaft dar, nicht ein Element oder Objekt mit einer Instanz.
Eigenschaftenelementsyntax für Auflistungstypen
Die XAML-Spezifikation erfordert, dass XAML-Prozessorimplementierungen Eigenschaften identifizieren, bei deren Werttyp es sich um eine Auflistung handelt. Die WPF-Implementierung basiert auf verwaltetem Code, und der zugehörige XAML-Prozessor identifiziert Auflistungstypen mit einer der folgenden Methoden:
Implementierung von IList
Implementierung von IDictionary
Ableitung von Array (Weitere Informationen zu Arrays in XAML finden Sie unter x:Array-Markuperweiterung.)
Wenn es sich beim Typ einer Eigenschaft um eine Auflistung handelt, muss der abgeleitete Auflistungstyp nicht im Markup angegeben werden. Stattdessen werden die Elemente der Auflistung als ein oder mehrere untergeordnete Elemente des Auflistungseigenschaftenelements angegeben. Die einzelnen Elemente werden beim Laden als Objekt ausgewertet und zur Auflistung hinzugefügt, indem die Add-Methode der impliziten Auflistung aufgerufen wird. Beispiel: Die Triggers-Eigenschaft von Style verwendet den speziellen Auflistungstyp TriggerCollection. Im Markup muss jedoch keine TriggerCollection instanziiert werden. Stattdessen geben Sie mindestens ein Trigger-Element als Elemente innerhalb des Style.Triggers-Eigenschaftenelements an, wobei Trigger (oder eine abgeleitete Klasse) als Elementtyp für die stark typisierte und implizite TriggerCollection erwartet wird.
<Style x:Key="SpecialButton" TargetType="{x:Type Button}">
<Style.Triggers>
<Trigger Property="Button.IsMouseOver" Value="true">
<Setter Property = "Background" Value="Red"/>
</Trigger>
<Trigger Property="Button.IsPressed" Value="true">
<Setter Property = "Foreground" Value="Green"/>
</Trigger>
</Style.Triggers>
</Style>
Eine Eigenschaft kann sowohl ein Auflistungstyp als auch die XAML-Inhaltseigenschaft für diesen Typ und davon abgeleitete Typen sein.
Ein implizites Auflistungselement erstellt einen Member in der logischen Struktur, auch wenn es im Markup nicht als Element erscheint. In der Regel führt der Konstruktor des besitzenden Typs die Instanziierung für die Auflistung aus, mit der die Auflistung der Struktur hinzugefügt wird.
Tipp
Die allgemeinen Listen- und Wörterbuchschnittstellen (IList<T> und IDictionary<TKey, TValue>) werden für die Auflistungserkennung durch den WPF-XAML-Prozessor nicht unterstützt. Sie können jedoch als Basisklasse die List<T>-Klasse verwenden, da sie IList direkt implementiert, bzw. die Dictionary<TKey, TValue>-Klasse, da diese IDictionary direkt implementiert.
XAML-Inhaltssyntax
Die XAML-Inhaltssyntax wird nur bei Klassen aktiviert, die ContentPropertyAttribute als Teil der Klassendeklaration angeben. Für ContentPropertyAttribute ist ein Parameter erforderlich, der die Eigenschaft mit dem Namen angibt, die als Inhaltseigenschaft für den Elementtyp definiert ist (einschließlich abgeleitete Klassen). Die so festgelegte Eigenschaft ist die XAML-Inhaltseigenschaft eines Elements. Bei der Verarbeitung mit einem XAML-Prozessor werden alle zwischen dem öffnenden und schließenden Tag des Elements gefundenen untergeordneten Elemente sowie innerer Text als Wert dieser XAML-Inhaltseigenschaft zugewiesen. Sie sind berechtigt, Eigenschaftenelemente für die Inhaltseigenschaft anzugeben und das Markup explizit vorzunehmen. Diese Methode bietet einen gelegentlichen Wert für die Markup-Klarheit oder als Markup-Stil, das Ziel einer Inhaltseigenschaft besteht jedoch in der Regel in der Strukturierung des Markups, sodass die Elemente, die intuitiv als übergeordnet-untergeordnet miteinander verbunden sind, direkt verschachtelt werden können. Eigenschaftenelementtags für andere Eigenschaften eines Elements werden nicht als "Inhalt" zugewiesen, sondern zuerst im Parserworkflow verarbeitet und nicht als "Inhalt" eingestuft.
Wie auch bei anderen Eigenschaften weist die XAML-Inhaltseigenschaft eines Objekts einen bestimmten Typ auf. Dabei kann es sich um den Object-Typ handeln. Mit dem Typ der Inhaltseigenschaft kann das Inhaltsmodell eines Objekts definiert werden. Beispiel: Der Typ Object ist lose, da ein beliebiges Objekt als Inhalt zugewiesen werden kann, selbst bei dieser losen Typisierung ist jedoch festgelegt, dass der Inhalt ein einzelnes Objekt sein muss. Dabei kann es sich um ein Auflistungsobjekt handeln, es kann jedoch nur ein Auflistungsobjekt als Inhalt zugewiesen werden.
In der WPF-Dokumentation werden die Inhaltsmodelle für bestimmte Typen auf den Klassenseiten für diesen Typ beschrieben oder als separate konzeptionelle Themen für Typfamilien aufgeführt. In diesem Fall enthalten die einzelnen relevanten Typverweise einen entsprechenden Link.
Inhaltssyntax für Auflistungstypen
Damit mehrere Objektelemente (oder innerer Text) als Inhalt akzeptiert werden, muss der Typ der Inhaltseigenschaft ein Auflistungstyp sein. Wie auch bei Eigenschaftenelementsyntax für Auflistungstypen muss ein XAML-Prozessor Typen als Auflistungstypen identifizieren. Falls ein Element über eine XAML-Inhaltseigenschaft verfügt und der Typ der XAML-Inhaltseigenschaft eine Sammlung ist, muss der implizite Auflistungstyp im Markup nicht als Objektelement angegeben werden, und die XAML-Inhaltseigenschaft muss nicht als Eigenschaftenelement angegeben werden. In diesem Fall können dem im Markup vorhandenen Inhaltsmodell mehrere untergeordnete Elemente als Inhalt zugewiesen werden. Das folgende Beispiel zeigt die Inhaltssyntax für eine abgeleitete Panel-Klasse. Bei allen abgeleiteten Klassen von Panel wird die XAML-Inhaltseigenschaft als Children festgelegt, was einen Wert vom Typ UIElementCollection erforderlich macht.
<Page
xmlns="https://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="https://schemas.microsoft.com/winfx/2006/xaml"
>
<StackPanel>
<Button>Button 1</Button>
<Button>Button 2</Button>
<Button>Button 3</Button>
</StackPanel>
</Page>
Beachten Sie, dass weder das Eigenschaftenelement für Children noch das Element für UIElementCollection im Markup erforderlich ist. Dies ist ein Entwurfsfeature von XAML mit dem Zweck, dass rekursiv enthaltene Elemente, mit denen eine Benutzeroberfläche definiert wird, intuitiver als Struktur verschachtelter Elemente mit unmittelbaren hierarchischen Beziehungen dargestellt wird, d. h. ohne überflüssige Eigenschaftenelementtags oder Auflistungsobjekte. UIElementCollection kann im Markup nicht als Objektelement angegeben werden. Da die einzige Verwendung die einer impliziten Auflistung ist, macht UIElementCollection keinen öffentlichen Standardkonstruktur verfügbar und kann aus diesem Grund nicht als Objektelement instanziiert werden.
Kombinieren von Eigenschaftenelementen und Objektelementen in einem Objekt mit einer Inhaltseigenschaft
Gemäß Deklaration in der XAML-Spezifikation kann ein XAML-Prozessor erzwingen, dass Objektelemente, die zum Laden von Daten in die XAML-Inhaltseigenschaft in einem Objektelement verwendet werden, zusammenhängend sein müssen und nicht kombiniert werden können. Diese Einschränkung zur Verhinderung der Kombination von Eigenschaftenelementen und Inhalt wird vom WPF-XAML-Prozessor erzwungen.
Sie können ein untergeordnetes Objektelement als erstes unmittelbares Markup in einem Objektelement angeben. Dann können Sie Eigenschaftenelemente angeben. Sie können auch ein oder mehrere Eigenschaftenelemente, dann Inhalt und dann weitere Eigenschaftenelemente angeben. Nach dem Eigenschaftenelement, das dem Inhalt folgt, können Sie jedoch keinen weiteren Inhalt angeben, sondern lediglich weitere Eigenschaftenelemente.
Diese Anforderung an die Abfolge von Inhalt und Eigenschaftenelementen gilt nicht für inneren Text, der als Inhalt verwendet wird. Es ist jedoch empfehlenswert, inneren Text zusammenhängend anzugeben, da signifikante Leerzeichen im Markup schwer zu erkennen sind, wenn Eigenschaftenelemente mit innerem Text kombiniert werden.
Angefügte Eigenschaften
Bei angefügten Eigenschaften handelt es sich um ein in XAML eingeführtes Programmierungskonzept mit dem Zweck, dass Eigenschaften mit einem Typ definiert werden und diesen als Besitzer haben, jedoch in beliebigen Elementen festgelegt werden können. Das primäre Szenario für angefügte Eigenschaften ist die Aktivierung von untergeordneten Elementen in einer Elementstruktur, um Informationen an ein übergeordnetes Element zu übermitteln, ohne dass ein umfassendes gemeinsam genutztes Objektmodell über alle Elemente hinweg erforderlich ist. Umgekehrt können angefügte Eigenschaften von übergeordneten Elementen verwendet werden, um Informationen an untergeordnete Elemente zu übermitteln. Weitere Informationen zu angefügten Eigenschaften und dazu, wie Sie eigene angefügte Eigenschaften erstellen, finden Sie unter Übersicht über angefügte Eigenschaften.
Die für angefügte Eigenschaften verwendete Syntax ähnelt der Eigenschaftenelementsyntax insofern, dass ebenfalls eine Typname.Eigenschaftenname-Kombination angegeben wird. Es gibt jedoch zwei wichtige Unterschiede:
Sie können die Typname.Eigenschaftenname-Kombination auch dann verwenden, wenn Sie eine angefügte Eigenschaft mittels Attributsyntax festlegen. Angefügte Eigenschaften sind der einzige Fall, bei dem der Eigenschaftenname in der Attributsyntax qualifiziert werden muss.
Sie können auch Eigenschaftenelementsyntax für angefügte Eigenschaften verwenden. Typischerweise ist der in der Eigenschaftenelementsyntax angegebene Typname jedoch das Objektelement, in dem das Eigenschaftenelement enthalten ist. Wenn Sie auf eine angefügte Eigenschaft verweisen, ist der Typname die Klasse, die die angefügte Eigenschaft definiert, nicht das Container-Objektelement.
Angefügte Ereignisse
Bei angefügten Ereignissen handelt es sich um ein weiteres in XAML eingeführtes Programmierungskonzept mit dem Zweck, dass Ereignisse mit einem Typ definiert werden, Handler jedoch an beliebige Objekte angefügt werden können. Bei dem Typ, mit dem ein angefügtes Ereignis definiert wird, handelt es sich oft um einen statischen Typ, der einen Dienst definiert, und in einigen Fällen werden diese angefügten Ereignisse über einen Routingereignisalias in Typen verfügbar gemacht, die den Dienst verfügbar machen. Handler für angefügte Ereignisse werden mit Attributsyntax angegeben. Die Attributsyntax wird für angefügte Ereignisse ebenfalls erweitert, um die Verwendung einer Typname.Ereignisname-Kombination zu ermöglichen, wobei Typname die Klasse ist, die Add- und Remove-Ereignishandleraccessoren für die angefügte Ereignisinfrastruktur bereitstellt, und Ereignisname der Ereignisname ist.
XML-Namespaces
In keinem der vorangehenden Syntaxbeispiele wurde ein anderer Namespace als der Standardnamespace angegeben. In typischen WPF-Anwendungen wird der Standardnamespace als WPF-Namespace angegeben. Sie können einen anderen als den Standardnamespace angeben und weiterhin dieselbe Syntax verwenden. Sie müssen jedoch bei jeder benannten Klasse, die im Standardnamespace nicht verfügbar ist, dem Klassennamen das Präfix des XML-Namespace voranstellen, das für die Zuordnung des entsprechenden CLR-Namespace verwendet wurde. Beispiel: <custom:MyElement/> dient als Objektelementsyntax zur Instanziierung einer Instanz der MyElement-Klasse, wobei der CLR-Namespace, der die Klasse enthält (und möglicherweise auch die externe Assembly, die den Namespace enthält), zuvor dem custom-Präfix zugeordnet wurde.
Weitere Informationen über XML-Namespaces und XAML finden Sie unter XAML-Namespaces und Namespacezuordnung.
Markuperweiterungen
XAML definiert eine Programmierentität für Markuperweiterungen, mit der die reguläre Handhabung von Attributen und Objektelementen durch den XAML-Prozessor ergänzt werden kann, wobei die Verarbeitung in eine Sicherungsklasse zurückgestellt wird. Bei der WPF-Implementierung eines XAML-Prozessors wird die abstrakte MarkupExtension-Klasse als Basis für alle von WPF unterstützten Markuperweiterungen verwendet. Zur Kennzeichnung der Markuperweiterung für den XAML-Prozessor bei Verwendung von Attributsyntax wird die öffnende geschweifte Klammer ({) verwendet, gefolgt von einem beliebigen anderen Zeichen mit Ausnahme der schließenden geschweiften Klammer (}). Die erste Zeichenfolge nach der öffnenden geschweiften Klammer muss auf die Klasse verweisen, die das spezifische Erweiterungsverhalten bereitstellt, wobei die Teilzeichenfolge "Extension" im Verweis weggelassen werden kann, wenn diese Teilzeichenfolge Teil des eigentlichen Klassennamens ist. Darauf kann ein einzelnes Leerzeichen folgen. Die darauf folgenden Zeichen bis zur schließenden geschweiften Klammer werden von der Erweiterungsimplementierung als Eingabe verwendet. Die Markuperweiterungen in WPF dienen hauptsächlich dazu, eine Möglichkeit bereitzustellen, bei der Verwendung von Attributsyntax auf andere bereits vorhandene Objekte oder zurückgestellte Verweise auf Objekte zu verweisen, die zur Laufzeit ausgewertet werden. Beispiel: Für eine einfache Datenbindung geben Sie statt des Werttyps, der normalerweise von einer gegebenen Eigenschaft verwendet wird, die Markuperweiterung {Bindung} an. Viele der Markuperweiterungen ermöglichen die Verwendung einer Attributsyntax für Eigenschaften, was andernfalls nicht möglich wäre. Beispiel: Ein Style-Objekt ist ein relativ komplexer Referenztyp, der mehrere andere Eigenschaften enthält, von denen jede einzelne byref-Objekte und keine Primitiven verwendet. Stile werden jedoch in der Regel als Ressourcen erstellt, und dann wird mit einer der zwei Markuperweiterungen, die eine Ressource anfordern, darauf verwiesen. Die Erweiterung stellt die Auswertung des Eigenschaftenwerts in eine Ressourcensuche zurück und ermöglicht die Bereitstellung der Style-Eigenschaft, wobei der Typ Style verwendet wird, in Attributsyntax wie folgt:
<Button Style="{StaticResource MyStyle}">My button</Button>
Hier identifiziert StaticResource die StaticResourceExtension-Klasse, die die Markuperweiterungsimplementierung bereitstellt. Die nächste Zeichenfolge MyStyle wird als Eingabe für den nicht standardmäßigen StaticResourceExtension-Konstruktor verwendet, wobei der angeforderte ResourceKey durch den Parameter aus der Erweiterungszeichenfolge deklariert wird. MyStyle wird als x:Key-Attribut-Wert eines Style erwartet, der als Ressource definiert ist. Die Verwendung von StaticResource-Markuperweiterung erfordert, dass die Ressource verwendet wird, um den Style-Eigenschaftenwert über die Logik einer statische Ressourcensuche zum Ladezeitpunkt bereitzustellen.
Weitere Informationen über Markuperweiterungen finden Sie unter Markuperweiterungen und XAML. Referenzen zu Markuperweiterungen und anderen XAML-Programmierfunktionen finden Sie unter Sprachfeatures des XAML-Namespace (x:) und XAML-definierte WPF-Namespaceerweiterungen.
Optionale und nicht zu empfehlende Verwendungen von XAML
Optionale Verwendungen von Eigenschaftenelementen
Zu den optionalen Verwendungen von Eigenschaftenelementen gehört die explizite Angabe von Elementinhaltseigenschaften, die vom XAML-Prozessor als implizit behandelt werden. Beispiel: Wenn Sie den Inhalt eines Menu deklarieren, können Sie die Items-Auflistung des Menu explizit als ein <Menu.Items>-Eigenschaftenelementtag deklarieren und jedes MenuItem in <Menu.Items> platzieren, statt das implizite XAML-Prozessorverhalten zu verwenden, bei dem jedes untergeordnete Element eines Menu ein MenuItem sein muss, die alle in die Items-Auflistung eingefügt werden. In einigen Fällen kann mit den optionalen Verwendungsmöglichkeiten die Objektstruktur im Markup verständlicher dargestellt werden. Oder Sie können durch ein explizit angegebenes Eigenschaftenelement Markup vermeiden, das technisch seinen Zweck erfüllt, dessen Darstellung jedoch eher verwirrend ist, wie z. B. verschachtelte Markuperweiterungen in einem Attributwert.
Voll qualifizierte Attribute (Typname.Membername)
Die Form Typname.Membername für Attribute kann universeller verwendet werden als nur bei Routingereignissen, in anderen Anwendungen ist diese Form jedoch überflüssig, und Sie sollten sie zugunsten eines besseren Markupformats und besserer Lesbarkeit vermeiden. Die drei Verweise auf das Background-Attribut im folgenden Beispiel sind vollständig äquivalent:
<Button Background="Blue">Background</Button>
<Button Button.Background="Blue">Button.Background</Button>
<Button Control.Background="Blue">Control.Background</Button>
Button.Background funktioniert, da die qualifizierte Suche für diese Eigenschaft nach Button erfolgreich ist (Background wurde vom Steuerelement geerbt) und Button die Klasse des Objektelements oder eine Basisklasse ist. Control.Background funktioniert, da die Control-Klasse Background definiert und Control eine Button-Basisklasse ist.
Das folgende Beispiel mit der Form Typname.Membername funktioniert jedoch nicht und wird kommentiert:
<!--<Button Label.Background="Blue">Does not work</Button> -->
Label ist eine weitere abgeleitete Klasse von Control. Wenn Sie Label.Background in einem Label-Objektelement angegeben hätten, hätte diese Methode funktioniert. Da Label jedoch nicht die Klasse oder Basisklasse von Button ist, verarbeitet der XAML-Prozessor Label.Background dann als angefügte Eigenschaft. Da es sich bei Label.Background nicht um eine angefügte Eigenschaft handelt, schlägt diese Methode fehl.
Basistypname.Membername-Eigenschaftenelemente
So wie die Form Typname.Membername für Attributsyntax funktioniert, kann die Form Basistypname.Membername für Eigenschaftenelementsyntax verwendet werden. Beispiel:
<Button>Control.Background PE
<Control.Background>
<LinearGradientBrush StartPoint="0,0" EndPoint="1,1">
<GradientStop Color="Yellow" Offset="0.0" />
<GradientStop Color="LimeGreen" Offset="1.0" />
</LinearGradientBrush>
</Control.Background>
</Button>
Hier wurde das Eigenschaftenelement als Control.Background angegeben, obwohl das Eigenschaftenelement in Button enthalten war.
Wie die Form Typname.Membername bei Attributen ist aber auch die Form Basistypname.Membername kein gutes Markupformat und sollte Gründen der Lesbarkeit nicht verwendet werden.
Siehe auch
Konzepte
Übersicht über Abhängigkeitseigenschaften
XAML und benutzerdefinierte Klassen