Delen via


Markeringsextensies en WPF XAML

In dit onderwerp wordt het concept van markeringsextensies voor XAML geïntroduceerd, met inbegrip van de syntaxisregels, het doel en het klasseobjectmodel dat hierop van toepassing is. Markup-extensies zijn een algemene functie van de XAML-taal en van de .NET-implementatie van XAML-services. In dit onderwerp worden specifieke markeringsextensies beschreven voor gebruik in WPF XAML.

XAML-processors en -markeringen

Over het algemeen kan een XAML-parser een kenmerkwaarde interpreteren als een letterlijke tekenreeks die naar een primitief type kan worden geconverteerd, of op de een of andere manier naar een object converteren. Een dergelijk middel is door te verwijzen naar een typeconversieprogramma; dit wordt beschreven in het onderwerp TypeConverters en XAML. Er zijn echter scenario's waarin verschillend gedrag vereist is. Een XAML-processor kan bijvoorbeeld worden geïnstrueerd dat een waarde van een kenmerk niet mag resulteren in een nieuw object in de objectgrafiek. In plaats daarvan moet het kenmerk resulteren in een objectgrafiek die een verwijzing maakt naar een al geconstrueerd object in een ander deel van de grafiek of een statisch object. Een ander scenario is dat een XAML-processor kan worden geïnstrueerd om een syntaxis te gebruiken die niet-standaardargumenten levert aan de constructor van een object. Dit zijn de typen scenario's waarin een markeringsextensie de oplossing kan bieden.

Syntaxis van de basismarkeringsextensie

Een markeringsextensie kan worden geïmplementeerd om waarden op te geven voor eigenschappen in een kenmerkgebruik, eigenschappen in het gebruik van een eigenschapselement of beide.

Wanneer een kenmerkwaarde wordt opgegeven, is de syntaxis die een markeringsextensie voor een XAML-processor onderscheidt, de aanwezigheid van openende en sluitende accolades ({ en }). Het type markupextensie wordt vervolgens geïdentificeerd door het teksttoken dat direct volgt na het openen van de accolades.

Wanneer deze wordt gebruikt in de syntaxis van het eigenschapselement, is een markeringsextensie visueel hetzelfde als elk ander element dat wordt gebruikt om een eigenschapselementwaarde op te geven: een XAML-elementdeclaratie die verwijst naar de uitbreidingsklasse voor markeringen als een element, tussen punthaken (<>).

extensies voor XAML-Defined markeringen

Er bestaan verschillende markeringsextensies die niet specifiek zijn voor de WPF-implementatie van XAML, maar in plaats daarvan implementaties van intrinsieken of functies van XAML als taal. Deze markeringsextensies worden geïmplementeerd in de System.Xaml-assembly als onderdeel van de algemene .NET Framework XAML-services en bevinden zich in de XAML-taal XAML-naamruimte. In termen van algemeen gebruik van markeringen zijn deze markeringsextensies doorgaans identificeerbaar door het x: voorvoegsel in het gebruik. De MarkupExtension basisklasse (ook gedefinieerd in System.Xaml) biedt het patroon dat alle markeringsextensies moeten gebruiken om te worden ondersteund in XAML-lezers en XAML-schrijvers, waaronder in WPF XAML.

  • x:Type levert het Type-object voor het benoemde type. Deze faciliteit wordt het vaakst gebruikt in stijlen en sjablonen. Zie x:Type Markup Extension voor meer informatie.

  • x:Static produceert statische waarden. De waarden zijn afkomstig van code-entiteiten van het waardetype die niet rechtstreeks het type van de waarde van een doeleigenschap zijn, maar kunnen worden geëvalueerd op dat type. Zie x:Static Markup Extension voor meer informatie.

  • x:Null geeft null aan als een waarde voor een eigenschap en kan worden gebruikt voor kenmerken of eigenschapselementwaarden. Zie x:Null-markeringsextensie voor meer informatie.

  • x:Array biedt ondersteuning voor het maken van algemene matrices in XAML-syntaxis, voor gevallen waarin de verzamelingsondersteuning van WPF-basiselementen en controlemodellen opzettelijk niet wordt gebruikt. Zie x:Array Markup Extension voor meer informatie.

Opmerking

Het x: voorvoegsel wordt gebruikt voor de typische XAML-naamruimtetoewijzing van de XAML-taal intrinsiek, in het hoofdelement van een XAML-bestand of -productie. De Visual Studio-sjablonen voor WPF-toepassingen initiëren bijvoorbeeld een XAML-bestand met behulp van deze x: toewijzing. U kunt een ander voorvoegseltoken kiezen in uw eigen XAML-naamruimtetoewijzing, maar in deze documentatie wordt ervan uitgegaan dat de standaardtoewijzing x: wordt gebruikt als een manier om de entiteiten te identificeren die een gedefinieerd onderdeel van de XAML-naamruimte voor de XAML-taal zijn, in plaats van de standaardnaamruimte wpF of andere XAML-naamruimten die niet zijn gerelateerd aan een specifiek framework.

Markup-extensies voor WPF-Specific

De meest voorkomende markeringsextensies die worden gebruikt in WPF-programmering zijn extensies die resourceverwijzingen (StaticResource en DynamicResource) ondersteunen en die ondersteuning bieden voor gegevensbinding (Binding).

  • StaticResource biedt een waarde voor een eigenschap door de waarde van een al gedefinieerde resource te vervangen. Uiteindelijk wordt er een StaticResource evaluatie uitgevoerd bij het laden van XAML, en er is geen toegang tot de objecthiërarchie tijdens runtime. Zie de staticResource Markup-extensie voor meer informatie.

  • DynamicResource biedt een waarde voor een eigenschap door deze waarde toe te wijzen als een runtime-verwijzing naar een resource. Een dynamische resourceverwijzing dwingt telkens een nieuwe zoekactie af wanneer een dergelijke resource wordt geopend en heeft tijdens runtime toegang tot de objectgrafiek. Om deze toegang te krijgen, worden de concepten die door DynamicResource worden aangegeven ondersteund door afhankelijkheidseigenschappen in het WPF-eigenschappensysteem en geëvalueerde expressies. Daarom kunt u alleen gebruiken DynamicResource voor een afhankelijkheidseigenschapsdoel. Zie de DynamicResource Markup-extensie voor meer informatie.

  • Binding biedt een gegevensgebonden waarde voor een eigenschap, met behulp van de gegevenscontext die van toepassing is op het bovenliggende object tijdens runtime. Deze markeringsextensie is relatief complex, omdat hiermee een aanzienlijke inlinesyntaxis wordt ingeschakeld voor het opgeven van een gegevensbinding. Zie Binding Markup Extension voor meer informatie.

  • RelativeSource biedt broninformatie voor een Binding die door verschillende mogelijke relaties in de runtimeobjectstructuur kan navigeren. Dit biedt gespecialiseerde sourcing voor bindingen die zijn gemaakt in sjablonen voor meerdere toepassingen of die in code worden gemaakt zonder volledige kennis van de omringende objectstructuur. Zie RelativeSource MarkupExtension voor meer informatie.

  • TemplateBinding hiermee kan een besturingselementsjabloon waarden gebruiken voor sjablooneigenschappen die afkomstig zijn van door objectmodel gedefinieerde eigenschappen van de klasse die de sjabloon gaat gebruiken. Met andere woorden, de eigenschap in de sjabloondefinitie heeft toegang tot een context die alleen bestaat nadat de sjabloon is toegepast. Zie de TemplateBinding Markup-extensie voor meer informatie. Zie TemplateBinding voor meer informatie over het praktische gebruik van.

  • ColorConvertedBitmap ondersteunt een relatief geavanceerd imaging-scenario. Zie de markeringsextensie ColorConvertedBitmap voor meer informatie.

  • ComponentResourceKey en ThemeDictionary ondersteunen aspecten van het opzoeken van resources, met name voor resources en thema's die zijn verpakt met aangepaste componenten. Zie ComponentResourceKey Markup Extension, ThemeDictionary Markup Extension of Control Authoring Overview voor meer informatie.

*Extensieklassen

Voor zowel de algemene XAML-taal als WPF-specifieke markeringsextensies wordt het gedrag van elke markeringsextensie geïdentificeerd aan een XAML-processor via een *Extension klasse die is afgeleid van MarkupExtensionen een implementatie van de ProvideValue methode biedt. Deze methode op elke extensie biedt het object dat wordt geretourneerd wanneer de markup extension wordt geëvalueerd. Het geretourneerde object wordt doorgaans geëvalueerd op basis van de verschillende tekenreekstokens die worden doorgegeven aan de markeringsextensie.

De klasse biedt bijvoorbeeld StaticResourceExtension de oppervlakte-implementatie van de werkelijke zoekfunctie voor resources, zodat de ProvideValue implementatie het object retourneert dat wordt aangevraagd, waarbij de invoer van die specifieke implementatie een tekenreeks is die wordt gebruikt om de resource op te zoeken op basis x:Keyvan de bijbehorende. Veel van deze implementatiedetails zijn onbelangrijk als u een bestaande markeringsextensie gebruikt.

Sommige markeringsextensies gebruiken geen tekenreekstokenargumenten. Dit komt doordat ze een statische of consistente waarde retourneren, of omdat context voor welke waarde moet worden geretourneerd, beschikbaar is via een van de services die via de serviceProvider parameter worden doorgegeven.

Het *Extension naamgevingspatroon is voor het gemak en de consistentie. Het is niet noodzakelijk dat een XAML-processor die klasse identificeert als ondersteuning voor een markup-extensie. Zolang uw codebase System.Xaml bevat en .NET Framework XAML Services-implementaties gebruikt, is alles wat nodig is om te worden herkend als een XAML-markeringsextensie om af te leiden van MarkupExtension en ondersteuning te bieden voor een bouwsyntaxis. WPF definieert uitbreidingsklassen voor markeringen die niet voldoen aan het *Extension naamgevingspatroon, bijvoorbeeld Binding. Normaal gesproken is de reden hiervoor dat de klasse scenario's ondersteunt buiten pure ondersteuning voor markeringsuitbreidingen. In het geval van Binding, die klasse ondersteunt runtime-toegang tot methoden en eigenschappen van het object voor scenario's die niets te maken hebben met XAML.

Uitbreidingsklasse-interpretatie van initialisatietekst

De tekenreekstokens na de naam van de markup-extensie en nog steeds binnen de accolades worden geïnterpreteerd door een XAML-processor op een van de volgende manieren:

  • Een komma vertegenwoordigt altijd het scheidingsteken of de delimiter van afzonderlijke tokens.

  • Als de afzonderlijke gescheiden tokens geen gelijktekens bevatten, wordt elk token behandeld als een constructorargument. Elke constructorparameter moet worden opgegeven als het type dat door die handtekening wordt verwacht en in de juiste volgorde die door die handtekening wordt verwacht.

    Opmerking

    Een XAML-processor moet de constructor aanroepen die overeenkomt met het aantal argumenten van het aantal paren. Als u daarom een aangepaste markeringsextensie implementeert, moet u niet meerdere constructors met hetzelfde aantal argumenten opgeven. Het gedrag van een XAML-processor als er meer dan één markup-uitbreidingsconstructorpad met hetzelfde aantal parameters bestaat, is niet gedefinieerd. U moet echter verwachten dat een XAML-processor een uitzondering mag werpen bij gebruik als deze situatie bestaat in de definities van het markeringsuitbreidingstype.

  • Als de afzonderlijke gescheiden tokens gelijktekens bevatten, roept een XAML-processor eerst de parameterloze constructor aan voor de markeringsextensie. Vervolgens wordt elk naam=waardepaar geïnterpreteerd als een eigenschapsnaam die bestaat in de markeringsextensie en een waarde die aan die eigenschap moet worden toegewezen.

  • Als er een parallel resultaat is tussen het constructorgedrag en het gedrag van de eigenschapsinstelling in een markeringsextensie, maakt het niet uit welk gedrag u gebruikt. Het is gebruikelijker om deeigenschapswaardeparen= te gebruiken voor markeringsextensies met meer dan één settable-eigenschap, als dit uw markeringen opzettelijker maakt en u minder waarschijnlijk per ongeluk constructorparameters transponeert. (Wanneer u eigenschap=waardeparen opgeeft, zijn deze eigenschappen mogelijk in willekeurige volgorde.) Er is ook geen garantie dat een markeringsextensie een constructorparameter levert waarmee alle eigenschappen van de settabel worden ingesteld. Bijvoorbeeld, Binding is een markeringsextensie met veel eigenschappen die via de extensie kunnen worden ingesteld in de vorm van eigenschap=-waarde, maar Binding ondersteunt alleen twee constructors: een parameterloze constructor en een die een eerste pad instelt.

  • Een letterlijke komma kan niet worden doorgegeven aan een markeringsextensie zonder escapement.

Escape-reeksen en opmaakuitbreidingen

Kenmerkafhandeling in een XAML-processor gebruikt de accolades als indicatoren van een markeringsuitbreidingsreeks. Het is ook mogelijk om, indien nodig, een letterlijke accolade als waarde voor een kenmerkt attribuut te produceren door een escape-sequentie in te voeren met behulp van een leeg accoladespaar gevolgd door de letterlijke accolade. Zie {} Escape Sequence - Markeringsextensie.

Nesting van markup-extensies in XAML-gebruik

Het nesten van meerdere markup-extensies wordt ondersteund en elke markup-extensie wordt van binnenuit eerst geëvalueerd. Denk bijvoorbeeld aan het volgende gebruik:

<Setter Property="Background"
  Value="{DynamicResource {x:Static SystemColors.ControlBrushKey}}" />

In deze context wordt de x:Static instructie eerst geëvalueerd en wordt een tekenreeks geretourneerd. Die tekenreeks wordt vervolgens gebruikt als het argument voor DynamicResource.

Syntaxis van markeringsextensies en eigenschapselement

Wanneer een objectelement wordt gebruikt dat een waarde voor een eigenschapselement vult, is een extensieklasse voor markeringen visueel niet te onderscheiden van een typisch objectelement met typesteun dat kan worden gebruikt in XAML. Het praktische verschil tussen een typisch objectelement en een markeringsextensie is dat de markeringsextensie wordt geëvalueerd op een getypte waarde of wordt uitgesteld als een expressie. Daarom zullen de mechanismen voor mogelijke typefouten van eigenschapswaarden voor de markeringsextensie verschillen, vergelijkbaar met hoe een late gebonden eigenschap wordt behandeld in andere programmeermodellen. Een gewoon objectelement wordt geëvalueerd voor typeovereenkomst met de doeleigenschap die wordt ingesteld wanneer de XAML wordt geparseerd.

De meeste opmaakextensies, wanneer deze worden gebruikt in de syntaxis van objectelementen om een eigenschapselement te vullen, zouden geen inhoud of verdere syntaxis van het eigenschapselement bevatten. Zo sluit u de objectelement-tag en geeft u geen subelementen op. Wanneer een objectelement wordt aangetroffen door een XAML-processor, wordt de constructor voor die klasse aangeroepen, waarmee het object wordt geïnstitueerd dat is gemaakt op basis van het geparseerde element. Een uitbreidingsklasse voor markeringen is niet anders: als u wilt dat de opmaakextensie bruikbaar is in de syntaxis van objectelementen, moet u een constructor zonder parameters opgeven. Sommige bestaande markeringsextensies hebben ten minste één vereiste eigenschapswaarde die moet worden opgegeven voor effectieve initialisatie. Zo ja, dan wordt die eigenschapswaarde doorgaans gegeven als een eigenschapskenmerk voor het objectelement. Op de referentiepagina's voor XAML-naamruimte (x:) taalfuncties en WPF XAML-extensies worden markeringsextensies met vereiste eigenschappen (en de namen van de vereiste eigenschappen) genoteerd. Verwijzingspagina's zien ook als de syntaxis van objectelementen of kenmerksyntaxis niet is toegestaan voor bepaalde markeringsextensies. Een opmerkelijk geval is x:Array Markup Extension, die geen ondersteuning biedt voor de syntaxis van kenmerken omdat de inhoud van die matrix moet worden opgegeven binnen de tagging als inhoud. De matrixinhoud wordt verwerkt als algemene objecten, waardoor er geen standaardtypeconversieprogramma voor het kenmerk haalbaar is. Voor de extensie x:Array Markup is ook een type parameter vereist.

Zie ook