Översikt över markeringstillägg för XAML
Markeringstillägg är en XAML-teknik för att hämta ett värde som inte är en primitiv eller en specifik XAML-typ. För attributanvändning använder markeringstillägg den kända teckensekvensen för en inledande klammerparentes {
för att ange omfånget för markeringstillägget och en avslutande klammerparentes }
för att avsluta. När du använder .NET XAML Services kan du använda några av de fördefinierade XAML-språktilläggen från System.Xaml-sammansättningen. Du kan också underklassa från klassen MarkupExtension, som är definierad i System.Xaml, och definiera dina egna markup extensioner. Eller så kan du använda markeringstillägg som definierats av ett visst ramverk om du redan refererar till det ramverket.
När en markup-tilläggsanvändning tillgås kan XAML-objektskrivaren tillhandahålla tjänster till en anpassad MarkupExtension-klass via en tjänstanslutningspunkt i MarkupExtension.ProvideValue-återställningen. Tjänsterna kan användas för att hämta kontext om användningen, specifika funktioner för objektskrivaren, XAML-schemakontexten och så vidare.
XAML-definierade tillägg för markering
Flera markup-förlängningar implementeras av .NET XAML Services för stöd av XAML-språket. Dessa tillägg motsvarar delar av specifikationen av XAML som språk. Dessa kan vanligtvis identifieras av det x:
prefixet i syntaxen enligt den vanliga användningen. .NET XAML Services-implementeringar för dessa XAML-språkelement härleds alla från den MarkupExtension basklassen.
Not
Det x:
prefixet används för den typiska XAML-namnområdesmappningen för XAML-språknamnområdet i rotelementet i en XAML-produktion. Till exempel initierar Visual Studio-projektet och sidmallar för olika specifika ramverk en XAML-fil med hjälp av den här x:
mappning. Du kan välja en annan prefixtoken i din egen XAML-namnområdesmappning, men den här dokumentationen förutsätter att standardmappningen x:
som ett sätt att identifiera de entiteter som är en definierad del av XAML-språk-XAML-namnområdet, i motsats till ett specifikt ramverks standardnamnområde för XAML eller andra godtyckliga CLR- eller XML-namnområden.
x:Type
x:Type
tillhandahåller objektet Type för den namngivna typen. Den här funktionen används oftast i uppskjutningsmekanismer som använder underliggande CLR-typ och typhärledning som grupperingsmoniker eller identifierare. WPF-format och mallar samt deras användning av TargetType
egenskaper är ett specifikt exempel. Mer information finns i x:Type Markup Extension.
x:Static
x:Static
genererar statiska värden från kodentiteter av värdetyp som inte direkt är typen av en egenskaps värde, men som kan utvärderas till den typen. Detta är användbart för att ange värden som redan finns som välkända konstanter i en typdefinition. Mer information finns i x:Static Markup Extension.
x:Null
x:Null
anger null
som ett värde för en XAML-medlem. Beroende på designen av specifika typer eller större ramverksbegrepp är null
inte alltid ett standardvärde för en egenskap eller det underförstådda värdet för ett tomt strängattribut. Mer information finns i x:Null Markup Extension.
x:Array
x:Array
stöder skapande av allmänna matriser i XAML-syntax i fall där samlingsstöd som tillhandahålls av baselement och kontrollmodeller avsiktligt inte används. Mer information finns i x:Array Markup Extension. I XAML 2009 används matriser som språkpri primitiver i stället för som ett tillägg. Mer information finns i XAML 2009 Language Features.
x:Referens
x:Reference
är en del av XAML 2009, en förlängning av den ursprungliga språkuppsättningen (2006).
x:Reference
representerar en referens till ett annat befintligt objekt i ett objektdiagram. Objektet identifieras av dess x:Name
. Mer information finns i x:Reference Markup Extension.
Övriga x: Konstruktioner
Det finns andra x:
konstruktioner som stöder XAML-språkfunktioner, men de implementeras inte som markeringstillägg. För mer information, se XAML-namnområde (x:) språkfunktioner.
Basklassen för MarkupExtension
Om du vill definiera ett anpassat tillägg för markering som kan interagera med standardimplementeringarna av XAML-läsare och XAML-skrivare i System.Xaml härleder du en klass från den abstrakta MarkupExtension-klassen. Klassen har en metod att åsidosätta, vilket är ProvideValue. Du kan också behöva definiera ytterligare konstruktorer för att stödja argument för användningen av markeringstillägget och matchande egenskaper för inställbara objekt.
Via ProvideValuehar ett anpassat tillägg för markering åtkomst till en tjänstkontext som rapporterar miljön där markeringstillägget anropas av en XAML-processor. I sökvägen för inläsning är detta vanligtvis en XamlObjectWriter. I spara sökvägen är detta vanligtvis en XamlXmlWriter. Varje rapporterar tjänstkontexten som en intern XAML-tjänstleverantörskontextklass som implementerar ett tjänstleverantörsmönster. Mer information om tillgängliga tjänster och vad de representerar finns i Type Converters and Markup Extensions for XAML.
Din markupförlängningsklass måste använda en offentlig åtkomstnivå. XAML-processorer måste alltid kunna instansiera markupförlängningens stödfunktionens klass för att använda dess tjänster.
Definiera supporttypen för ett anpassat tillägg för markering
När du använder .NET XAML-tjänster eller ramverk som bygger på .NET XAML-tjänster har du två alternativ för hur du namnger stödtypen för markeringstillägget. Typnamnet är relevant för hur XAML-objektskrivare försöker komma åt och anropa en stödtyp för markeringstillägg när de stöter på en användning av markeringstillägg i XAML. Använd någon av följande namngivningsstrategier:
- Ange typnamnet som en exakt matchning till XAML-markeringstoken. Om du till exempel vill ha stöd för en
{Collate ...}
tilläggsanvändning namnger du supporttypenCollate
. - Ge typnamnet som användningssträngstoken plus suffixet
Extension
. Om du till exempel vill ha stöd för en{Collate ...}
tilläggsanvändning namnger du supporttypenCollateExtension
.
Uppslagsordningen är att leta efter Extension
-suffixklassnamn först och sedan leta efter klassnamnet utan Extension
-suffixet.
Från markeringsanvändningsperspektivet är det giltigt att inkludera Extension
-suffixet som en del av användningen. Detta fungerar dock som om Extension
verkligen är en del av klassnamnet, och XAML-objektskrivare skulle misslyckas med att matcha en stödklass för markeringstillägg för den användningen om supportklassen inte hade Extension
suffixet.
Den parameterlösa konstruktorn
För alla stödtyper för markeringstillägg bör du exponera en offentlig parameterlös konstruktor. En parameterlös konstruktor krävs för alla fall där en XAML-objektskrivare instansierar markeringstillägget från en objektelementanvändning. Att stödja användning av objektelement är en rimlig förväntan för ett markeringstillägg, särskilt vid serialisering. Du kan dock implementera ett markeringstillägg utan en offentlig konstruktor om du bara har för avsikt att stödja attributanvändningar för markeringstillägget.
Om ditt markeringstillägg inte har några argument krävs en konstruktör utan parametrar för att kunna användas.
Konstruktormönster och positionsargument för ett anpassat markeringstillägg
För ett markup-tillägg med avsedd argumentanvändning måste de publika konstruktorerna motsvara lägena för avsedd användning. Med andra ord, om markeringstillägget är utformat för att kräva ett positionsargument som en giltig användning bör du ha stöd för en offentlig konstruktor med en indataparameter som använder positionsargumentet.
Anta till exempel att Collate
markeringstillägg är avsett att endast stödja ett läge där det finns ett positionsargument som representerar dess läge, som anges som en CollationMode
uppräkningskonstant. I det här fallet bör det finnas en konstruktor med följande form:
public Collate(CollationMode collationMode) {...}
På en grundläggande nivå är argumenten som skickas till ett markeringstillägg en sträng eftersom de vidarebefordras från markeringsattributvärdena. Du kan göra alla dina argument till strängar och arbeta med indata på den nivån. Du har dock åtkomst till viss bearbetning som inträffar innan argumenten för markup-tillägg skickas till supportklassen.
Bearbetningen fungerar konceptuellt som om markeringstillägget är ett objekt som ska skapas och sedan anges dess medlemsvärden. Varje angiven egenskap som ska anges utvärderas på liknande sätt som en angiven medlem kan anges för ett skapat objekt när XAML parsas. Det finns två viktiga skillnader:
- Som tidigare nämnts behöver en stödtyp för markeringstillägg inte ha någon parameterlös konstruktor för att kunna instansieras i XAML. Objektkonstruktionen skjuts upp tills dess möjliga argument i textsyntaxen tokeniseras och utvärderas som antingen positionella eller namngivna argument, och lämplig konstruktor anropas då.
- Användning av markup-extensioner kan kapslas. Det innersta markeringstillägget utvärderas först. Därför kan du anta en sådan användning och deklarera en av byggparametrarna som en typ som kräver att en värdekonverterare (till exempel en "markup extension") genereras.
Ett beroende av sådan bearbetning visades i föregående exempel. .NET XAML Services XAML-objektskrivare bearbetar uppräkningskonstantnamn till uppräknade värden på intern nivå.
Bearbetning av textsyntax för en positionsparameter för markeringstillägg kan också förlita sig på en typkonverterare som är associerad med den typ som finns i byggargumentet.
Argumenten kallas för positionsargument eftersom den ordning i vilken token i användningen påträffas motsvarar positionsordningen för den konstruktorparameter som de tilldelas till. Tänk till exempel på följande konstruktorsignatur:
public Collate(CollationMode collationMode, object collateThis) {...}
En XAML-processor förväntar sig två positionsargument för det här markeringstillägget. Om det fanns en användning {Collate AlphaUp,{x:Reference circularFile}}
, skickas AlphaUp
-token till den första parametern och utvärderas som en CollationMode
-uppräkning som en namngiven konstant. Resultatet av den inre x:Reference
skickas till den andra parametern och utvärderas som ett objekt.
I de XAML-angivna reglerna för syntax och bearbetning av markeringstillägg är kommatecknet avgränsaren mellan argument, oavsett om dessa argument är positionsargument eller namngivna argument.
Dubblett antal av positionella argument
Om en XAML-objektskrivare stöter på en markeringstilläggsanvändning med positionella argument och det finns flera konstruktorargument som tar det antalet argument (en duplicerad aritet), är det inte nödvändigtvis ett fel. Beteendet beror på en anpassningsbar XAML-schemakontextinställning, SupportMarkupExtensionsWithDuplicateArity. Om SupportMarkupExtensionsWithDuplicateArity är true
bör en XAML-objektskrivare inte bara utlösa ett undantag på grund av duplicerad aritet. Beteende utöver den punkten är inte strikt definierat. Det grundläggande designantagandet är att schemakontexten har typinformation tillgänglig för de specifika parametrarna och kan försöka explicita casts som matchar de duplicerade kandidaterna för att se vilken signatur som kan vara den bästa matchningen. Ett undantag kan fortfarande utlösas om inga signaturer kan klara de tester som införs av den specifika schemakontexten som körs på en XAML-objektskrivare.
Som standard är SupportMarkupExtensionsWithDuplicateArityfalse
i CLR-baserade XamlSchemaContext för .NET XAML Services. Standardvärdet XamlObjectWriter därför utlöser undantag om det påträffar en användning av markeringstillägg där det finns dubbletter av aritet i bakgrundstypens konstruktorer.
Namngivna argument för ett anpassat tillägg för markering
Markeringstillägg som anges av XAML kan också använda ett namngivet argumentformulär för användning. Vid den första nivån av tokenisering delas textsyntaxen in i argument. Förekomsten av ett likhetstecken (=) i ett argument identifierar ett argument som ett namngivet argument. Ett sådant argument tokeniseras också till ett namn/värde-par. Namnet i det här fallet namnger en offentlig uppsättningsbar egenskap för markeringstilläggets supporttyp. Om du har för avsikt att stödja namngivna argument bör du tillhandahålla dessa publika egenskaper som kan ställas in. Egenskaperna kan vara ärvda egenskaper så länge de förblir offentliga.
Åtkomst till tjänstleverantörskontext från en implementering av markeringstillägg
De tjänster som är tillgängliga är desamma för alla värdekonverterare. Skillnaden är hur varje värdekonverterare tar emot tjänstkontexten. Åtkomst till tjänster och tillgängliga tjänster dokumenteras i avsnittet Type Converters and Markup Extensions for XAML.
Användning av egenskapselement för en markup-extension
Scenarierna för användning av markeringstillägg är ofta utformade för att använda markeringstillägget i attributanvändning. Det är dock också möjligt att definiera backningsklassen för att stödja användning av egenskapselement.
Definiera en offentlig parameterlös konstruktor för att stödja användning av egenskapselement för ditt markeringstillägg. Detta bör vara en instanskonstruktor, inte en statisk konstruktor. Detta krävs eftersom en XAML-processor vanligtvis måste anropa den parameterlösa konstruktorn på alla objektelement som bearbetas från markering, och detta inkluderar markeringstilläggsklasser som objektelement. För avancerade scenarier kan du definiera byggvägar som inte är standard för klasser. (Mer information finns i x:FactoryMethod Directive.) Du bör dock inte använda dessa mönster för markup-tillägg eftersom det gör identifieringen av användningsmönstret mycket svårare, både för designers och för användare av rå markup.
Attribuering av en anpassad markup-utökning
För att stödja både designmiljöer och vissa XAML-objektskrivarscenarier bör du tillskriva en stödtyp för markeringstillägg med flera CLR-attribut. Dessa attribut rapporterar den avsedda användningen av markeringstillägget.
MarkupExtensionReturnTypeAttribute rapporterar Type information för den objekttyp som ProvideValue returnerar. Med sin rena signatur returnerar ProvideValueObject. Men olika konsumenter kanske vill ha mer exakt returtypsinformation. Detta inkluderar:
- Designverktyg och IDE:er, som kanske kan ge typanpassat stöd för användning av markup-förlängningar.
- Avancerade implementeringar av
SetMarkupExtension
-hanterare på målklasser, som kan förlita sig på reflektion för att fastställa ett markeringstilläggs returtyp i stället för att förgrena specifika kända MarkupExtension implementeringar efter namn.
Serialisering av användning av markeringstillägg
När en XAML-objektskrivare bearbetar en användning av markeringstillägget och anropar ProvideValuesparas kontexten för att det tidigare var en markeringstilläggsanvändning i XAML-nodströmmen men inte i objektdiagrammet. I objektdiagrammet bevaras endast värdet. Om du har designscenarier eller andra orsaker till att spara den ursprungliga markeringstilläggsanvändningen i serialiserade utdata måste du utforma din egen infrastruktur för att spåra användningen av markeringstillägget från XAML-nodströmmen för belastningssökväg. Du kan implementera beteenden för att återskapa elementen i nodströmmen från belastningssökvägen och spela tillbaka dem till XAML-skrivare för serialisering i spara-sökvägen, och därmed ersätta värdet på lämplig position i nodströmmen.
Markeringstillägg i XAML-nodströmmen
Om du arbetar med en XAML-nodström längs inläsningssökvägen, visas användning av markeringstillägg i nodströmmen som ett objekt.
Om användningen av markeringstillägget använder positionella argument representeras det som ett startobjekt med ett initieringsvärde. Som en grov textrepresentation liknar nodströmmen följande:
StartObject
(XamlType är markeringstilläggets definitionstyp, inte dess returtyp)
StartMember
(namnet på XamlMember är _InitializationText
)
Value
(värdet är positionsargumenten som en sträng, inklusive de mellanliggande avgränsarna)
EndMember
EndObject
En markeringstilläggsanvändning med namngivna argument representeras som ett objekt med medlemmar i relevanta namn, varje uppsättning med textsträngsvärden.
För att anropa ProvideValue
-implementeringen av ett markeringstillägg krävs XAML-schema-kontexten eftersom det kräver typmappning och innebär att skapa en instans av en stödtyp för markeringstillägg. Det här är en anledning till att markeringstilläggsanvändningar bevaras på det här sättet i standardnodströmmarna för .NET XAML Services – läsardelen av en inläsningssökväg har ofta inte den nödvändiga XAML-schemakontexten tillgänglig.
Om du arbetar med en XAML-nodström på spara-sökvägen finns det oftast ingenting i representationen av objektgrafen som kan informera dig att objektet som ska serialiseras ursprungligen tillhandahölls genom användning av ett markeringstillägg och ett ProvideValue
-resultat. Scenarier som behöver bevara användning av markeringstillägg för avrundning och samtidigt samla in andra ändringar i objektdiagrammet måste utforma sina egna tekniker för att bevara kunskapen om en användning av påläggstillägg från de ursprungliga XAML-indata. Om du till exempel vill återställa användningen av markeringstillägget kan du behöva arbeta med nodströmmen på spara-sökvägen för att återställa användningen av markeringstillägg eller utföra någon typ av sammanslagning mellan den ursprungliga XAML och den rundade XAML-filen. Vissa XAML-implementeringsramverk som WPF använder mellanliggande typer (uttryck) för att representera fall där markeringstilläggsanvändningar angav värdena.
Se även
.NET Desktop feedback