Dela via


Markeringstillägg och WPF XAML

Det här avsnittet beskriver begreppet tillägg för markering för XAML, inklusive deras syntaxregler, syfte och den klassobjektmodell som ligger till grund för dem. Tillägg för markering är en allmän funktion i XAML-språket och för .NET-implementeringen av XAML-tjänster. Det här avsnittet beskriver specifikt tillägg för markering för användning i WPF XAML.

XAML-processorer och tillägg för markering

Generellt sett kan en XAML-parser antingen tolka ett attributvärde som en literalsträng som kan konverteras till en primitiv, eller konvertera det till ett objekt på något sätt. Ett sådant sätt är genom att referera till en typkonverterare. detta dokumenteras i ämnet TypeConverters och XAML. Det finns dock scenarier där olika beteenden krävs. En XAML-processor kan till exempel instrueras att ett värde för ett attribut inte ska resultera i ett nytt objekt i objektdiagrammet. I stället bör attributet resultera i ett objektdiagram som refererar till ett redan konstruerat objekt i en annan del av grafen eller ett statiskt objekt. Ett annat scenario är att en XAML-processor kan instrueras att använda en syntax som ger icke-standardargument till konstruktorn för ett objekt. Det här är de typer av scenarier där ett tillägg för markering kan tillhandahålla lösningen.

Grundläggande markeringstilläggssyntax

En markup-extension kan implementeras för att ange värden för egenskaper i en attributanvändning, egenskaper i en egenskapselementanvändning, eller båda.

När den används för att ange ett attributvärde är syntaxen som utmärker en uppmärkningstilläggssekvens till en XAML-processor användningen av inledande och avslutande klammerparenteser ({ och }). Typen av markeringstillägg identifieras sedan av strängtoken omedelbart efter den inledande klammerparentesen.

När det används i egenskapselementsyntaxen är ett tillägg för markering visuellt detsamma som andra element som används för att ange ett egenskapselementvärde: en XAML-elementdeklaration som refererar till markeringstilläggsklassen som ett element inom vinkelparenteser (<>).

XAML-Defined Tillägg för markering

Det finns flera tillägg som inte är specifika för WPF-implementeringen av XAML, utan i stället är implementeringar av inbyggda funktioner eller funktioner i XAML som språk. Dessa markeringstillägg implementeras i System.Xaml-assemblyn som en del av de allmänna .NET Framework XAML-tjänsterna och finns inom XAML-namnområdet inom XAML-språket. När det gäller vanlig markeringsanvändning kan dessa påläggstillägg vanligtvis identifieras av prefixet x: i användningen. Basklassen MarkupExtension (definieras även i System.Xaml) ger det mönster som alla tillägg för markering ska använda för att kunna användas i XAML-läsare och XAML-skrivare, inklusive i WPF XAML.

  • x:Type tillhandahåller objektet Type för den namngivna typen. Den här funktionen används oftast i format och mallar. Mer information finns i x:Typ Markup-tillägg.

  • x:Static genererar statiska värden. Värdena kommer från kodentiteter av typen värde som inte direkt är typen för ett målvärdegenskapens värde, men som kan utvärderas till den typen. Mer information finns i x:Static Markup Extension.

  • x:Null specificerar null som ett värde för en egenskap och kan användas antingen för attribut eller för egenskapselementvärden. Mer information finns i x:Null-markeringstillägg.

  • x:Array ger stöd för skapande av allmänna matriser i XAML-syntax, för fall där samlingsstödet som tillhandahålls av WPF-baselement och kontrollmodeller avsiktligt inte används. Mer information finns i x:Matrismarkeringstillägg.

Anmärkning

Prefixet x: används för den typiska XAML-namnområdesmappningen av det inbyggda XAML-språket i rotelementet i en XAML-fil eller -produktion. Visual Studio-mallarna för WPF-program initierar till exempel en XAML-fil med hjälp av den här x: mappningen. Du kan välja en annan prefixtoken i din egen XAML-namnområdesmappning, men den här dokumentationen förutsätter standardmappningen x: som ett sätt att identifiera de entiteter som är en definierad del av XAML-namnområdet för XAML-språket, i motsats till WPF-standardnamnområdet eller andra XAML-namnområden som inte är relaterade till ett specifikt ramverk.

WPF-Specific Tillägg för markering

De vanligaste påläggstilläggen som används i WPF-programmering är de som stöder resursreferenser (StaticResource och DynamicResource) och de som stöder databindning (Binding).

  • StaticResource tillhandahåller ett värde för en egenskap genom att ersätta värdet för en redan definierad resurs. En StaticResource utvärdering görs slutligen vid XAML-inläsningstid och har inte åtkomst till objektdiagrammet vid körning. Mer information finns i StaticResource Markup-tillägget.

  • DynamicResource ger ett värde för en egenskap genom att hänvisa till det värdet som en körningsreferens till en resurs. En dynamisk resursreferens initierar en ny sökning varje gång en sådan resurs används och har åtkomst till objektdiagrammet vid körningstid. För att få den här åtkomsten stöds DynamicResource-konceptet av beroendeegenskaper i WPF-egenskapssystemet och av utvärderade uttryck. Därför kan du bara använda DynamicResource för ett beroendeegenskapsmål. Mer information finns i DynamicResource Markup-tillägget.

  • Binding tillhandahåller ett databundet värde för en egenskap med hjälp av den datakontext som gäller för det överordnade objektet vid körningstid. Det här markeringstillägget är relativt komplext eftersom det möjliggör en omfattande infälld syntax för att specificera en databindning. Mer information finns i Bindningsmarkeringstillägg.

  • RelativeSource innehåller källinformation för en Binding som kan navigera i flera möjliga relationer i körningsobjektträdet. Detta ger specialiserade källor för bindningar som skapas i mallar med flera användningsområden eller skapas i kod utan fullständig kunskap om det omgivande objektträdet. Mer information finns i RelativeSource MarkupExtension.

  • TemplateBinding aktiverar en kontrollmall för att använda värden för mallade egenskaper som kommer från objektmodelldefinierade egenskaper för klassen som ska använda mallen. Med andra ord kan egenskapen i malldefinitionen komma åt en kontext som bara finns när mallen har tillämpats. Se TemplateBinding Markup Extension för mer information. Mer information om praktisk användning av TemplateBindingfinns i Formatering med ControlTemplates Sample.

  • ColorConvertedBitmap stöder ett relativt avancerat bildscenario. Mer information finns i ColorConvertedBitmap-markeringstillägg.

  • ComponentResourceKey och ThemeDictionary stöder aspekter av resurssökning, särskilt för resurser och teman som är paketerade med anpassade kontroller. Mer information finns i ComponentResourceKey Markup Extension, ThemeDictionary Markup Extension eller Control Authoring Overview.

*Tilläggsklasser

För både det allmänna XAML-språket och WPF-specifika tillägg identifieras beteendet för varje markeringstillägg för en XAML-processor via en *Extension klass som härleds från MarkupExtensionoch ger en implementering av ProvideValue metoden. Den här metoden för varje tillägg innehåller det objekt som returneras när markeringstillägget utvärderas. Det returnerade objektet utvärderas vanligtvis baserat på de olika strängtoken som skickas till markeringstillägget.

Klassen tillhandahåller till exempel StaticResourceExtension ytimplementeringen av den faktiska resurssökningen så att dess ProvideValue implementering returnerar det objekt som begärs, där indata för den specifika implementeringen är en sträng som används för att leta upp resursen med dess x:Key. Mycket av den här implementeringsinformationen är oviktig om du använder ett befintligt tillägg för markering.

Vissa markeringstillägg använder inte strängtokenargument. Det beror antingen på att de returnerar ett statiskt eller konsekvent värde, eller på att kontexten för vilket värde som ska returneras är tillgänglig via en av de tjänster som skickas via parametern serviceProvider .

Namngivningsmönstret *Extension är för enkelhetens skull och konsekvens. Det är inte nödvändigt för att en XAML-processor ska kunna identifiera den klassen som stöd för ett markeringstillägg. Så länge din kodbas innehåller System.Xaml och använder .NET Framework XAML Services-implementeringar är allt som krävs för att identifieras som ett XAML-tillägg att härleda från MarkupExtension och stödja en konstruktionssyntax. WPF definierar markeringstilläggsaktiveringsklasser som inte följer namngivningsmönstret *Extension , till exempel Binding. Orsaken till detta är vanligtvis att klassen stöder scenarier utöver rent stöd för markup-utökningar. När det gäller Bindingstöder den klassen körningsåtkomst till metoder och egenskaper för objektet för scenarier som inte har något att göra med XAML.

Tilläggsklasstolkning av initieringstext

Strängtoken som följer påläggstilläggets namn och som fortfarande finns inom klammerparenteserna tolkas av en XAML-processor på något av följande sätt:

  • Ett kommatecken representerar alltid separations- eller avgränsartecknet för enskilda enheter.

  • Om de enskilda avgränsade token inte innehåller likhetstecken behandlas varje token som ett konstruktorargument. Varje konstruktorparameter måste anges som den typ och i den ordning som förväntas av signaturen.

    Anmärkning

    En XAML-processor måste anropa konstruktorn som matchar argumentantalet för antalet par. Om du därför implementerar ett anpassat tillägg för markering ska du inte ange flera konstruktorer med samma argumentantal. Beteendet för hur en XAML-processor beter sig om det finns fler än en markeringstilläggskonstruktorsökväg med samma parameterantal är inte definierat, men du bör förvänta dig att en XAML-processor får utlösa ett undantag om användningen om den här situationen finns i definitionerna för markeringstilläggstyp.

  • Om de enskilda avgränsade token innehåller likhetstecken anropar en XAML-processor först den parameterlösa konstruktorn för markeringstillägget. Sedan tolkas varje namn=värdepar som ett egenskapsnamn som finns på markeringstillägget och ett värde som ska tilldelas till den egenskapen.

  • Om det finns ett parallellt resultat mellan konstruktorns beteende och egenskapsinställningsbeteendet i ett markeringstillägg spelar det ingen roll vilket beteende du använder. Det är vanligare att användaegenskapsvärdeparen= för markeringstillägg som har mer än en inställningsbar egenskap, om så bara för att det gör markeringen mer avsiktlig och det är mindre troligt att du oavsiktligt transponerar konstruktorparametrar. (När du anger property=value pairs kan dessa egenskaper vara i valfri ordning.) Det finns heller ingen garanti för att ett tillägg för markering tillhandahåller en konstruktorparameter som anger var och en av dess inställbara egenskaper. Är till exempel Binding ett markeringstillägg, med många egenskaper som kan anges genom tillägget i egenskap=värde-form, men Binding stöder bara två konstruktorer: en parameterlös konstruktor och en som anger en inledande sökväg.

  • Ett literal kommatecken kan inte skickas till ett markeringstillägg utan escapement.

Escape-sekvenser och markeringstillägg

Attributhantering i en XAML-processor använder klammerparenteserna som indikatorer för en markeringstilläggssekvens. Det går också att skapa ett teckenattributvärde för en bokstavlig klammerparentes om det behövs, genom att ange en escape-sekvens med hjälp av ett tomt klammerpar följt av den bokstavliga klammerparentesen. Se {} Escape Sequence – markeringstillägg.

Nästla markup-tillägg i XAML-användning

Kapsling av flera markeringstillägg stöds och varje markeringstillägg utvärderas djupast först. Tänk till exempel på följande användning:

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

I den här användningen utvärderas instruktionen x:Static först och returnerar en sträng. Strängen används sedan som argument för DynamicResource.

Syntax för markeringstillägg och egenskapselement

När det används som ett objektelement som fyller ett egenskapselementvärde kan en markeringstilläggsklass visuellt inte skiljas från ett typiskt typbaserat objektelement som kan användas i XAML. Den praktiska skillnaden mellan ett typiskt objektelement och ett markeringstillägg är att markeringstillägget antingen utvärderas till ett typat värde eller skjuts upp och används som ett uttryck. Mekanismerna för eventuella typfel för egenskapsvärden för markeringstillägget skiljer sig därför åt, ungefär som hur en sen bindningsegenskap behandlas i andra programmeringsmodeller. Ett vanligt objektelement utvärderas för typmatchning mot den målegenskap som ställs in när XAML parsas.

De flesta markeringstillägg, när de används i objektelementsyntaxen för att fylla ett egenskapselement, skulle inte innehålla något innehåll eller någon ytterligare egenskapselementsyntax inom sig. Därför stänger du objektelementstaggen och anger inga underordnade element. När ett objektelement påträffas av en XAML-processor anropas konstruktorn för den klassen, vilket instansierar objektet som skapats från det parsade elementet. En markeringstilläggsklass skiljer sig inte åt: om du vill att markeringstillägget ska kunna användas i objektelementsyntaxen måste du ange en parameterlös konstruktor. Vissa befintliga markup-förlängningar har minst ett obligatoriskt egenskapsvärde som måste anges för effektiv initialisering. I så fall anges det egenskapsvärdet vanligtvis som ett egenskapsattribut för objektelementet. I referenssidorna XAML-namnrymd (x:) och WPF XAML-tillägg noteras markeringstillägg som har nödvändiga egenskaper (och namnen på de egenskaper som krävs). Referenssidor kommer också att notera om antingen objektelementsyntax eller attributsyntax inte tillåts för vissa tillägg för markering. Ett viktigt fall är x:Array Markup Extension, som inte kan stödja attributsyntax eftersom innehållet i matrisen måste anges i taggningen som innehåll. Matrisinnehållet hanteras som allmänna objekt, därför är ingen standardtypkonverterare för attributet möjlig. Dessutom kräver x:Array Markup Extension en type parameter.

Se även