Dela via


Definiera anpassade typer för användning med .NET XAML Services

När du definierar anpassade typer som är affärsobjekt eller är typer som inte är beroende av specifika ramverk, finns det vissa metodtips för XAML som du kan följa. Om du följer dessa metoder kan .NET XAML Services och dess XAML-läsare och XAML-skrivare identifiera XAML-egenskaperna för din typ och ge den lämplig representation i en XAML-nodström med hjälp av XAML-typsystemet. I det här avsnittet beskrivs metodtips för typdefinitioner, medlemsdefinitioner och CLR-attribut för typer eller medlemmar.

Konstruktormönster och typdefinitioner för XAML

Om du vill instansieras som ett objektelement i XAML måste en anpassad klass uppfylla följande krav:

  • Den anpassade klassen måste vara offentlig och måste exponera en parameterlös offentlig konstruktor. (Se följande avsnitt för kommentarer om strukturer.)

  • Den anpassade klassen får inte vara en kapslad klass. Den extra "punkt" i sökvägen med fullständigt namn gör divisionen klassnamnområde tvetydig och stör andra XAML-funktioner, till exempel anslutna egenskaper. Om ett objekt kan instansieras som ett objektelement kan det skapade objektet fylla egenskapselementformen för alla egenskaper som tar objektet som underliggande typ.

Du kan fortfarande ange objektvärden för typer som inte uppfyller dessa villkor om du aktiverar en värdekonverterare. Mer information finns i Type Converters and Markup Extensions for XAML.

Strukturer

Strukturer kan alltid konstrueras i XAML enligt CLR-definition. Det beror på att en CLR-kompilator implicit skapar en parameterlös konstruktor för en struktur. Den här konstruktorn initierar alla egenskapsvärden till standardvärdena.

I vissa fall är standardkonstruktionsbeteendet för en struktur inte önskvärt. Det kan bero på att strukturen är avsedd att fylla värden och fungera konceptuellt som en union. Som en union kan de inneslutna värdena ha ömsesidigt uteslutande tolkningar, och därför kan ingen av dess egenskaper anges. Ett exempel på en sådan struktur i WPF-ordlistan är GridLength. Sådana strukturer bör implementera en typkonverterare så att värdena kan uttryckas i attributformulär med hjälp av strängkonventioner som skapar olika tolkningar eller lägen för strukturvärdena. Strukturen bör också exponera liknande beteende för kodkonstruktion via en icke-parameterlös konstruktor.

Gränssnitt

Gränssnitt kan användas som underliggande typer av medlemmar. XAML-typsystemet kontrollerar den tilldelningsbara listan och förväntar sig att objektet som anges som värde kan tilldelas till gränssnittet. Det finns inget begrepp om hur gränssnittet måste presenteras som en XAML-typ så länge en relevant tilldelningsbar typ stöder XAML-byggkraven.

Fabriksmetoder

Fabriksmetoder är en XAML 2009-funktion. De ändrar XAML-principen att objekt måste ha parameterlösa konstruktorer. Fabriksmetoder dokumenteras inte i den här artikeln. Se x:FactoryMethod Directive.

Uppräkningar

Uppräkningar har XAML-beteende för intern typkonvertering. Uppräkningskonstantnamn som anges i XAML matchas mot den underliggande uppräkningstypen och returnerar uppräkningsvärdet till en XAML-objektskrivare.

XAML stöder en användning i flaggformat för uppräkningar med FlagsAttribute tillämpas. Mer information finns i XAML-syntax i detalj. (XAML-syntax i detalj är skriven för WPF-målgruppen, men det mesta av informationen i det ämnet är relevant för XAML som inte är specifikt för ett visst implementeringsramverk.)

Medlemsdefinitioner

Typer kan definiera medlemmar för XAML-användning. Det är möjligt för typer att definiera medlemmar som är XAML-användbara även om den specifika typen inte är XAML-användbar. Detta är möjligt på grund av CLR-arv. Så länge någon typ som ärver medlemmen stöder XAML-användning som en typ, och medlemmen stöder XAML-användning för sin underliggande typ eller har en inbyggd XAML-syntax tillgänglig, är den medlemmen XAML-användbar.

Egenskaper

Om du definierar egenskaper som en offentlig CLR-egenskap med hjälp av typiska CLR-get och set accessormönster och språkanpassade nyckelord kan XAML-typsystemet rapportera egenskapen som medlem med lämplig information för XamlMember egenskaper, till exempel IsReadPublic och IsWritePublic.

Specifika egenskaper kan aktivera en textsyntax genom att använda TypeConverterAttribute. Mer information finns i Type Converters and Markup Extensions for XAML.

Om det inte finns någon textsyntax eller inbyggd XAML-konvertering och om det inte finns någon ytterligare indirekt användning, till exempel användning av markeringstillägg, måste typen av en egenskap (TargetType i XAML-typsystemet) kunna returnera en instans till en XAML-objektskrivare genom att behandla måltypen som en CLR-typ.

Om du använder XAML 2009 kan x:Reference Markup Extension användas för att ange värden om de tidigare övervägandena inte uppfylls. Det är dock mer ett användningsproblem än ett typdefinitionsproblem.

Evenemang

Om du definierar händelser som en offentlig CLR-händelse kan XAML-typsystemet rapportera händelsen som medlem med IsEvent som true. Kabeldragning av händelsehanterare ligger inte inom omfånget för .NET XAML Services-funktioner. över till specifika ramverk och implementeringar.

Metoder

Infogad kod för metoder är inte en standardfunktion för XAML. I de flesta fall refererar du inte direkt till metodmedlemmar från XAML, och metodens roll i XAML är bara att ge stöd för specifika XAML-mönster. x:FactoryMethod-direktiv är ett undantag.

Fält

CLR-designriktlinjer avråder från icke-statiska fält. För statiska fält kan du endast komma åt statiska fältvärden via x:Static Markup Extension; I det här fallet gör du inget speciellt i CLR-definitionen för att exponera ett fält för användning av x:Static.

Medlemmar som kan kopplas

Anslutbara medlemmar exponeras för XAML via ett accessormetodmönster för en definierande typ. Själva den definierande typen behöver inte vara XAML-användbar som ett objekt. I själva verket är ett vanligt mönster att deklarera en tjänstklass vars roll är att äga den bifogande medlemmen och implementera relaterade beteenden, men inte fungera någon annan funktion, till exempel en UI-representation. I följande avsnitt representerar platshållaren PropertyName namnet på din bifogande medlem. Det namnet måste vara giltigt i XamlName Grammar.

Var försiktig med namnkollisioner mellan dessa mönster och andra metoder av en typ. Om det finns en medlem som matchar ett av mönstren kan den tolkas som en anslutningsbar medlemsanvändningsväg av en XAML-processor även om det inte var din avsikt.

GetPropertyName-accessorn

Signaturen för GetPropertyName-accessorn måste vara:

public static object GetPropertyName(object target)

  • Det target objektet kan anges som en mer specifik typ i implementeringen. Du kan använda detta för att begränsa användningen av din anslutningbara medlem. användningar utanför ditt avsedda omfång utlöser ogiltiga gjutna undantag som sedan visas av ett XAML-parsningsfel. Parameternamnet target är inte ett krav, men heter target av konventionen i de flesta implementeringar.

  • Returvärdet kan anges som en mer specifik typ i implementeringen.

Om du vill ha stöd för en TypeConverter aktiverad textsyntax för attributanvändning för den anslutbara medlemmen tillämpar du TypeConverterAttributeGetPropertyName-accessorn. Att tillämpa på get i stället för set kan verka icke-intuitivt; Den här konventionen kan dock stödja begreppet skrivskyddade bifogande medlemmar som är serialiserbara, vilket är användbart i designerscenarier.

SetPropertyName-accessorn

Signaturen för SetPropertyName-accessorn måste vara:

public static void SetPropertyName(object target, object value)

  • Det target objektet kan anges som en mer specifik typ i implementeringen, med samma logik och konsekvenser som beskrivs i föregående avsnitt.

  • Det value objektet kan anges som en mer specifik typ i implementeringen.

Kom ihåg att värdet för den här metoden är de indata som kommer från XAML-användningen, vanligtvis i attributformulär. Från attributformuläret måste det finnas stöd för värdekonverterare för en textsyntax och du kan tillskriva på GetPropertyNames-accessorn.

Kopplingsbara medlemslager

Accessor-metoderna räcker vanligtvis inte för att tillhandahålla ett sätt att placera anslutningsbara medlemsvärden i ett objektdiagram, eller för att hämta värden från objektdiagrammet och serialisera dem korrekt. För att kunna tillhandahålla den här funktionen måste de target objekten i de tidigare signaturerna för åtkomsten kunna lagra värden. Lagringsmekanismen bör vara förenlig med den anslutningbara medlemsprincipen att medlemmen kan kopplas till mål där den bifogande medlemmen inte finns med i medlemslistan. .NET XAML Services tillhandahåller en implementeringsteknik för anslutningsbara medlemslager via API:erna IAttachedPropertyStore och AttachablePropertyServices. IAttachedPropertyStore används av XAML-skrivarna för att identifiera butiksimplementeringen och bör implementeras på den typ som är target för åtkomstgivarna. De statiska AttachablePropertyServices-API:erna används i brödtexten för accessorerna och refererar till den anslutningsbara medlemmen av dess AttachableMemberIdentifier.

Korrekt attributering av dina typer, medlemmar och sammansättningar är viktigt för att kunna rapportera systeminformation av XAML-typ till .NET XAML Services. Rapportering av systeminformation av XAML-typ är relevant om någon av följande situationer gäller:

  • Du har för avsikt att använda dina typer med XAML-system som är direkt baserade på .NET XAML Services XAML-läsare och XAML-skrivare.
  • Du definierar eller använder ett XAML-användningsramverk som baseras på dessa XAML-läsare och XAML-skrivare.

En lista över varje XAML-relaterat attribut som är relevant för XAML-stöd för dina anpassade typer finns i XAML-Related CLR-attribut för anpassade typer och bibliotek.

Användning

Användning av anpassade typer kräver att markeringsförfattaren måste mappa ett prefix för sammansättningen och CLR-namnområdet som innehåller den anpassade typen. Den här proceduren är inte dokumenterad i det här avsnittet.

Åtkomstnivå

XAML är ett sätt att läsa in och instansiera typer som har en internal åtkomstnivå. Den här funktionen tillhandahålls så att användarkoden kan definiera sina egna typer och sedan instansiera dessa klasser från markering som också ingår i samma användarkodomfång.

Ett exempel från WPF är när användarkod definierar en UserControl som är avsedd som ett sätt att omstrukturera ett gränssnittsbeteende, men inte som en del av någon möjlig tilläggsmekanism som kan vara underförstådd genom att deklarera den stödjande klassen med public åtkomstnivå. En sådan UserControl kan deklareras med internal åtkomst om bakgrundskoden kompileras till samma sammansättning som den refereras till som en XAML-typ.

För ett program som läser in XAML under fullständigt förtroende och använder XamlObjectWriteraktiveras alltid inläsning av klasser med internal åtkomstnivå.

För ett program som läser in XAML under partiellt förtroende kan du styra åtkomstnivåegenskaperna med hjälp av XamlAccessLevel-API:et. Dessutom måste uppskjutningsmekanismer (till exempel WPF-mallsystemet) kunna sprida alla behörigheter på åtkomstnivå och bevara dem för utvärderingar av eventuell körningstid. Detta hanteras internt genom att skicka XamlAccessLevel information.

WPF-implementering

WPF XAML använder en partisk åtkomstmodell där åtkomst begränsas till AssemblyAccessTo för den sammansättning som är BAML-källan om BAML läses in under partiellt förtroende. Vid uppskjutning använder WPF IXamlObjectWriterFactory.GetParentSettings som en mekanism för att skicka information på åtkomstnivå.

I WPF XAML-terminologi är en intern typ en typ som definieras av samma sammansättning som även innehåller refererande XAML. En sådan typ kan mappas via ett XAML-namnområde som avsiktligt utelämnar sammansättningen= delen av en mappning, till exempel xmlns:local="clr-namespace:WPFApplication1". Om BAML refererar till en intern typ och den typen har internal åtkomstnivå genererar detta en GeneratedInternalTypeHelper-klass för sammansättningen. Om du vill undvika GeneratedInternalTypeHelpermåste du antingen använda public åtkomstnivå eller ta med den relevanta klassen i en separat sammansättning och göra sammansättningen beroende.

Se även