Not
Åtkomst till den här sidan kräver auktorisering. Du kan prova att logga in eller ändra kataloger.
Åtkomst till den här sidan kräver auktorisering. Du kan prova att ändra kataloger.
XAML som implementerats i CLR-ramverk (Common Language Runtime) stöder möjligheten att definiera en anpassad klass eller struktur i alla CLR-språk (Common Language Runtime) och sedan komma åt den klassen med XAML-markering. Du kan använda en blandning av WPF-definierade typer (Windows Presentation Foundation) och dina anpassade typer i samma markeringsfil, vanligtvis genom att mappa de anpassade typerna till ett XAML-namnområdesprefix. I det här avsnittet beskrivs de krav som en anpassad klass måste uppfylla för att kunna användas som ett XAML-element.
Anpassade klasser i program eller sammansättningar
Anpassade klasser som används i XAML kan definieras på två olika sätt: i koden bakom eller annan kod som producerar det primära WPF-programmet (Windows Presentation Foundation) eller som en klass i en separat sammansättning, till exempel en körbar fil eller DLL som används som ett klassbibliotek. Var och en av dessa metoder har särskilda fördelar och nackdelar.
Fördelen med att skapa ett klassbibliotek är att alla sådana anpassade klasser kan delas i många olika möjliga program. Ett separat bibliotek gör även versionshanteringsproblem för program enklare att kontrollera och förenklar skapandet av en klass där den avsedda klassanvändningen är som ett rotelement på en XAML-sida.
Fördelen med att definiera anpassade klasser i programmet är att den här tekniken är relativt enkel och minimerar de distributions- och testproblem som uppstår när du introducerar separata sammansättningar utöver det körbara huvudprogrammet.
Oavsett om de definieras i samma eller olika sammansättning måste anpassade klasser mappas mellan CLR-namnområdet och XML-namnområdet för att kunna användas i XAML som element. Se XAML-namnområden och namnområdesmappning för WPF XAML.
Krav för en anpassad klass som ett XAML-element
För att kunna instansieras som ett objektelement måste klassen uppfylla följande krav:
Din anpassade klass måste vara offentlig och ha stöd för en offentlig standardkonstruktor (parameterlös). (Se följande avsnitt för kommentarer om strukturer.)
Din anpassade klass får inte vara en kapslad klass. Kapslade klasser och "punkt" i deras allmänna CLR-användningssyntax stör andra WPF- och/eller XAML-funktioner, till exempel bifogade egenskaper.
Förutom att aktivera objektelementsyntax aktiverar objektdefinitionen även egenskapselementsyntax för andra offentliga egenskaper som tar objektet som värdetyp. Det beror på att objektet nu kan instansieras som ett objektelement och kan fylla egenskapselementvärdet för en sådan egenskap.
Strukturer
Strukturer som du definierar som anpassade typer kan alltid konstrueras i XAML i WPF . Det beror på att CLR-kompilatorerna implicit skapar en parameterlös konstruktor för en struktur som initierar alla egenskapsvärden till deras standardvärden. I vissa fall är standardkonstruktionsbeteendet och/eller objektelementanvändningen för en struktur inte önskvärt. Detta kan bero på att strukturen är avsedd att fylla värden och fungera konceptuellt som en union, där de värden som ingår kan ha ömsesidigt uteslutande tolkningar och därmed ingen av dess egenskaper kan anges. Ett WPF-exempel på en sådan struktur är GridLength. I allmänhet bör sådana strukturer implementera en typkonverterare så att värdena kan uttryckas i attributform med hjälp av strängkonventioner som skapar olika tolkningar eller lägen för strukturens värden. Strukturen bör också exponera liknande beteende för kodkonstruktion via en icke-parameterlös konstruktor.
Krav för egenskaper för en anpassad klass som XAML-attribut
Egenskaper måste referera till en eftervärdestyp (till exempel en primitiv) eller använda en klass för typ som antingen har en parameterlös konstruktor eller en dedikerad typkonverterare som en XAML-processor kan komma åt. I CLR XAML-implementeringen hittar XAML-processorer antingen sådana konverterare via inbyggt stöd för språkpri primitiver eller genom tillämpning av TypeConverterAttribute till en typ eller medlem i bakgrundstypdefinitioner
Egenskapen kan också referera till en abstrakt klasstyp eller ett gränssnitt. För abstrakta klasser eller gränssnitt är förväntningarna på XAML-parsning att egenskapsvärdet måste fyllas med konkreta klassinstanser som implementerar gränssnittet eller instanser av typer som härleds från den abstrakta klassen.
Egenskaper kan deklareras i en abstrakt klass, men kan endast ställas in på konkreta klasser som ärvda från den abstrakta klassen. Det beror på att det krävs en offentlig parameterlös konstruktor för klassen för att skapa objektelementet för klassen alls.
TypeConverter-aktiverad attributsyntax
Om du anger en dedikerad, tillskriven typkonverterare på klassnivå aktiverar den tillämpade typkonverteringen attributsyntax för alla egenskaper som behöver instansiera den typen. En typkonverterare aktiverar inte objektelementanvändning av typen. endast förekomsten av en parameterlös konstruktor för den typen möjliggör användning av objektelement. Därför är egenskaper som är typkonverterare aktiverade i allmänhet inte användbara i egenskapssyntaxen, såvida inte själva typen också stöder objektelementsyntax. Undantaget är att du kan ange en egenskapselementsyntax, men låta egenskapselementet innehålla en sträng. Den användningen motsvarar egentligen i stort sett en användning av attributsyntax, och en sådan användning är inte vanlig om det inte finns ett behov av mer robust white-space-hantering av attributvärdet. Följande är till exempel en egenskapselementanvändning som tar en sträng och motsvarande attributanvändning:
<Button>Hallo!
<Button.Language>
de-DE
</Button.Language>
</Button>
<Button Language="de-DE">Hallo!</Button>
Exempel på egenskaper där attributsyntax tillåts men egenskapselementsyntax som innehåller ett objektelement tillåts inte via XAML är olika egenskaper som använder Cursor typen . Klassen Cursor har en konverterare CursorConverterav dedikerad typ , men exponerar inte en parameterlös konstruktor, så Cursor egenskapen kan bara anges via attributsyntax även om den faktiska Cursor typen är en referenstyp.
Per-Property typkonverterare
Alternativt kan själva egenskapen deklarera en typkonverterare på egenskapsnivå. Detta möjliggör ett "minispråk" som instansierar objekt av typen av egenskapen inline, genom att bearbeta inkommande strängvärden för attributet som indata för en ConvertFrom operation baserat på relevant typ. Detta görs vanligtvis för att tillhandahålla en bekvämlighetsåtkomst, och inte som det enda sättet att aktivera inställningen av en egenskap i XAML. Det är dock också möjligt att använda typkonverterare för attribut där du vill använda befintliga CLR-typer som inte tillhandahåller antingen en parameterlös konstruktor eller en konverterare av typen attribut. Exempel från WPF-API:et är vissa egenskaper som använder typen CultureInfo . I det här fallet använde WPF den befintliga Microsoft .NET Framework-typen CultureInfo för att bättre hantera kompatibilitets- och migreringsscenarier som användes i tidigare versioner av ramverk, men CultureInfo typen stödde inte nödvändiga konstruktorer eller typkonvertering för att kunna användas som ett XAML-egenskapsvärde direkt.
När du exponerar en egenskap med XAML-användning bör du, särskilt om du är kontrollutvecklare, starkt överväga att stötta den egenskapen med beroendeegenskapen. Detta gäller särskilt om du använder den befintliga Windows Presentation Foundation-implementeringen (WPF) av XAML-processorn, eftersom du kan förbättra prestandan genom att använda DependencyProperty backing. En beroendeegenskap exponerar egenskapssystemfunktioner för din egenskap som användarna kommer att förvänta sig för en XAML-tillgänglig egenskap. Detta omfattar funktioner som animering, databindning och formatstöd. Mer information finns i Anpassade beroendeegenskaper och XAML-inläsnings- och beroendeegenskaper.
Skriva och använda en typkonverterare
Ibland måste du skriva en anpassad TypeConverter härledd klass för att tillhandahålla typkonvertering för din egenskapstyp. Anvisningar om hur du härleder och skapar en typkonverterare som kan stödja XAML-användning, och hur du tillämpar detta, finns i TypeConverterAttributeTypeConverters och XAML.
Krav för XAML-händelsehanterarattributsyntax för händelser i en anpassad klass
För att kunna användas som en CLR-händelse måste händelsen exponeras som en offentlig händelse i en klass som stöder en parameterlös konstruktor eller i en abstrakt klass där händelsen kan nås på härledda klasser. För att kunna användas bekvämt som en dirigerad händelse bör DIN CLR-händelse implementera explicita add metoder och remove metoder som lägger till och tar bort hanterare för CLR-händelsesignaturen och vidarebefordrar dessa hanterare till AddHandler metoderna och RemoveHandler . Dessa metoder lägger till eller tar bort hanterarna i det dirigerade händelsehanterararkivet på den instans som händelsen är kopplad till.
Anmärkning
Det går att registrera hanterare direkt för routade händelser med hjälp av AddHandler och att avsiktligt inte definiera en CLR-händelse som gör den routade händelsen tillgänglig. Detta rekommenderas vanligtvis inte eftersom händelsen inte aktiverar XAML-attributsyntax för att koppla hanterare, och den resulterande klassen erbjuder en mindre transparent XAML-vy över den typens funktioner.
Egenskaper för skrivsamling
Egenskaper som tar en samlingstyp har en XAML-syntax som gör att du kan ange objekt som läggs till i samlingen. Den här syntaxen har två viktiga funktioner.
Objektet som är samlingsobjektet behöver inte anges i objektelementsyntaxen. Förekomsten av den samlingstypen är implicit när du anger en egenskap i XAML som tar en samlingstyp.
Underordnade element i samlingsegenskapen i markup-språk bearbetas så att de blir medlemmar i samlingen. Vanligtvis utförs kodåtkomsten till medlemmarna i en samling via list-/ordlistemetoder som
Add, eller via en indexerare. Men XAML-syntaxen stöder inte metoder eller indexerare (undantag: XAML 2009 kan stödja metoder, men XAML 2009 begränsar möjliga WPF-användningar, se XAML 2009 Language Features). Samlingar är uppenbarligen ett mycket vanligt krav för att skapa ett träd med element, och du behöver ett sätt att fylla i dessa samlingar i deklarativ XAML. Därför bearbetas underordnade element i en samlingsegenskap genom att lägga till dem i samlingen som är värdet för samlingens egenskapstyp.
.NET Framework XAML Services-implementeringen och därmed WPF XAML-processorn använder följande definition för vad som utgör en samlingsegenskap. Egenskapens egenskapstyp måste implementera något av följande:
Implementerar IList.
Implementerar IDictionary.
Härleder från Array (mer information om matriser i XAML finns i x:Array Markup Extension.)
Implementerar IAddChild (ett gränssnitt som definieras av WPF).
Var och en av dessa typer i CLR har en Add metod som används av XAML-processorn för att lägga till objekt i den underliggande samlingen när objektdiagrammet skapas.
Anmärkning
De allmänna ListDictionary gränssnitten (IList<T> och IDictionary<TKey,TValue>) stöds inte för insamlingsidentifiering av WPF XAML-processorn. Du kan dock använda List<T>-klassen som basklass eftersom den implementerar IList direkt, eller Dictionary<TKey,TValue> som basklass eftersom den implementerar IDictionary direkt.
När du deklarerar en egenskap som hanterar en samling bör du vara försiktig med hur egenskapsvärdet sätts upp i nya instanser av typen. Ifall du inte implementerar egenskapen som en beroendeegenskap, är det tillräckligt att låta egenskapen använda ett fält som anropar konstruktorn för samlingstypen. Om din egenskap är en beroendeegenskap kan du behöva initiera samlingsegenskapen som en del av standardtypkonstruktorn. Det beror på att en beroendeegenskap tar sitt standardvärde från metadata och du vanligtvis inte vill att det initiala värdet för en samlingsegenskap ska vara en statisk, delad samling. Det bör finnas en samlingsinstans för varje instans av den innehållande typen. Mer information finns i egenanpassade beroendeegenskaper.
Du kan implementera en anpassad samlingstyp för din samlingsegenskap. På grund av implicit insamlingsegenskapsbehandling behöver den anpassade samlingstypen inte tillhandahålla en parameterlös konstruktor för att kunna användas implicit i XAML. Du kan dock ange en parameterlös konstruktor för samlingstypen. Detta kan vara en bra metod. Om du inte anger en parameterlös konstruktor kan du inte uttryckligen deklarera samlingen som ett objektelement. Vissa markeringsförfattare kanske föredrar att se den explicita samlingen som en fråga om markeringsformat. Dessutom kan en parameterlös konstruktor förenkla initieringskraven när du skapar nya objekt som använder din samlingstyp som ett egenskapsvärde.
Deklarera XAML-innehållsegenskaper
XAML-språket definierar begreppet XAML-innehållsegenskap. Varje klass som kan användas i objektsyntaxen kan ha exakt en XAML-innehållsegenskap. Om du vill deklarera en egenskap som XAML-innehållsegenskap för din klass, applicera ContentPropertyAttribute som en del av klassdefinitionen. Ange namnet på den avsedda XAML-innehållsegenskapen Name som i attributet. Egenskapen anges som en sträng efter namn, inte som en reflektionskonstruktion, till exempel PropertyInfo.
Du kan ange en samlingsegenskap som XAML-innehållsegenskap. Detta resulterar i en användning för den egenskapen där objektelementet kan ha ett eller flera underordnade element, utan mellanliggande element för samlingsobjekt eller egenskapselementtaggar. Dessa element behandlas sedan som värdet för XAML-innehållsegenskapen och läggs till i instansen för säkerhetskopieringssamlingen.
Vissa befintliga XAML-innehållsegenskaper använder egenskapstypen Object. Detta möjliggör en XAML-innehållsegenskap som kan ta primitiva värden, till exempel ett String och ett enda referensobjektvärde. Om du följer den här modellen ansvarar din typ för typbestämning och hantering av möjliga typer. Den typiska orsaken till en Object innehållstyp är att stödja både ett enkelt sätt att lägga till objektinnehåll som en sträng (som tar emot en standardbehandling för presentation) eller ett avancerat sätt att lägga till objektinnehåll som anger en presentation som inte är standard eller ytterligare data.
Serialisera XAML
I vissa scenarier, till exempel om du är kontrollförfattare, kanske du också vill försäkra dig om att alla objektrepresentationer som kan instansieras i XAML också kan serialiseras tillbaka till motsvarande XAML-markering. Serialiseringskrav beskrivs inte i det här avsnittet. Se Översikt över kontrollredigering och elementträd och serialisering.
Se även
.NET Desktop feedback