Condividi tramite


Strutture e concetti del flusso di nodi XAML

I lettori XAML e i writer XAML implementati nei servizi XAML .NET si basano sul concetto di progettazione di un flusso di nodi XAML. Il flusso di nodi XAML è una concettualizzazione di un set di nodi XAML. In questa concettualizzazione, un processore XAML esamina la struttura delle relazioni tra nodi nel codice XAML uno alla volta. In qualsiasi momento, esiste solo un record corrente o una posizione corrente in un flusso di nodi XAML aperto e molti aspetti del report API solo le informazioni disponibili da tale posizione. Il nodo corrente in un flusso di nodi XAML può essere descritto come oggetto, membro o valore. Trattando XAML come flusso di nodi XAML, i lettori XAML possono comunicare con i writer XAML e consentire a un programma di visualizzare, interagire o modificare il contenuto di un flusso di nodi XAML durante un percorso di caricamento o un'operazione di salvataggio che coinvolge XAML. La progettazione e la progettazione dell'API writer XAML e il concetto di flusso dei nodi XAML sono simili ai concetti e alle progettazioni e ai concetti di lettore e writer correlati, ad esempio IL MODELLO DOM (Document Object Model) XML e le classi XmlReader e XmlWriter. Questo argomento illustra i concetti relativi al flusso di nodi XAML e descrive come scrivere routine che interagiscono con le rappresentazioni XAML a livello di nodo XAML.

Caricamento di XAML in un lettore XAML

La classe base XamlReader non dichiara una particolare tecnica per caricare il codice XAML iniziale in un lettore XAML. Una classe derivata dichiara e implementa invece la tecnica di caricamento, incluse le caratteristiche generali e i vincoli dell'origine di input per XAML. Ad esempio, un XamlObjectReader legge un oggetto grafico, a partire dall'origine di input di un singolo oggetto che rappresenta la radice o la base. Il XamlObjectReader produce quindi un flusso di nodi XAML dal grafico degli oggetti.

La sottoclasse di servizi XAML .NET definita XamlReader più importante è XamlXmlReader. XamlXmlReader carica il codice XAML iniziale caricando un file di testo direttamente tramite un flusso o un percorso di file o indirettamente tramite una classe lettore correlata, ad esempio TextReader. Il XamlReader può essere considerato come contenente l'intera origine di input XAML dopo il caricamento. Tuttavia, l'API di base XamlReader è progettata in modo che il lettore interagisca con un singolo nodo del codice XAML. Al primo caricamento, il primo nodo singolo rilevato è la radice del codice XAML e il relativo oggetto iniziale.

Concetto di flusso del nodo XAML

Se si ha familiarità con un DOM, una metafora dell'albero o un approccio basato su query per accedere alle tecnologie basate su XML, un modo utile per concettualizzare un flusso di nodi XAML è il seguente. Si supponga che il codice XAML caricato sia un DOM o un albero in cui ogni nodo possibile viene espanso in modo lineare e quindi presentato in modo lineare. Man mano che si passano attraverso i nodi, è possibile attraversare "in" o "out" livelli rilevanti per un DOM, ma il flusso di nodi XAML non tiene traccia in modo esplicito perché questi concetti di livello non sono rilevanti per un flusso di nodi. Il flusso di nodi ha una posizione "corrente", ma a meno che non siano state archiviate altre parti del flusso come riferimenti, ogni aspetto del flusso del nodo diverso dalla posizione del nodo corrente non è visualizzato.

Il concetto di flusso di nodi XAML ha il vantaggio notevole che, se si passa attraverso l'intero flusso di nodi, si è certi di aver elaborato l'intera rappresentazione XAML; non è necessario preoccuparsi che una query, un'operazione DOM o un altro approccio non lineare per l'elaborazione delle informazioni non abbia perso parte della rappresentazione XAML completa. Per questo motivo, la rappresentazione del flusso di nodi XAML è ideale sia per connettere lettori XAML che writer XAML e per fornire un sistema in cui è possibile inserire il proprio processo che agisce tra le fasi di lettura e scrittura di un'operazione di elaborazione XAML. In molti casi, l'ordinamento dei nodi nel flusso di nodi XAML viene deliberatamente ottimizzato o riordinato dai lettori XAML rispetto al modo in cui l'ordine potrebbe apparire nel testo di origine, nel file binario o nell'oggetto grafico. Questo comportamento è progettato per applicare un'architettura di elaborazione XAML in cui i writer XAML non sono mai in una posizione in cui devono tornare "indietro" nel flusso del nodo. Idealmente, tutte le operazioni di scrittura XAML devono essere in grado di agire in base al contesto dello schema e alla posizione corrente del flusso del nodo.

Ciclo di nodi di lettura di base

Un ciclo di nodi di lettura di base per l'analisi di un flusso di nodi XAML è costituito dai concetti seguenti. Ai fini dei cicli di nodi come descritto in questo argomento, si supponga di leggere un file XAML leggibile e basato su testo usando XamlXmlReader. I collegamenti in questa sezione fanno riferimento all'API del ciclo di nodi XAML specifica implementata da XamlXmlReader.

  • Assicurarsi di non essere alla fine del flusso del nodo XAML (controllare IsEofo usare il valore restituito Read). Se si è alla fine del flusso, non è presente alcun nodo corrente e si dovrebbe uscire.

  • Controllare il tipo di nodo attualmente esposto dal flusso di nodi XAML chiamando NodeType.

  • Se hai un writer di oggetti XAML associato connesso direttamente, in genere chiami WriteNode a questo punto.

  • In base alla quale XamlNodeType viene segnalato come nodo corrente o record corrente, chiamare uno dei seguenti elementi per ottenere informazioni sul contenuto del nodo:

    • Per un NodeType di StartMember o EndMember, chiamare Member per ottenere informazioni XamlMember su un membro. Il membro potrebbe essere un XamlDirectivee pertanto potrebbe non essere necessariamente un membro convenzionale definito dal tipo dell'oggetto precedente. Ad esempio, x:Name applicato a un oggetto viene visualizzato come membro XAML in cui IsDirective è true e il Name del membro è Name, con altre proprietà che indicano che questa direttiva si trova nello spazio dei nomi XAML del linguaggio XAML.

    • Per un NodeType di StartObject o EndObject, chiamare Type per ottenere informazioni XamlType su un oggetto .

    • Per un NodeType di Value, chiamare Value. Un nodo è un valore solo se è l'espressione più semplice di un valore per un membro o il testo di inizializzazione per un oggetto . È tuttavia necessario essere consapevoli del comportamento di conversione dei tipi come documentato in una sezione futura di questo argomento.

    • Per un NodeType di NamespaceDeclaration, chiamare Namespace per ottenere informazioni sullo spazio dei nomi per un nodo dello spazio dei nomi.

  • Chiama Read per far avanzare il lettore XAML al nodo successivo nel flusso del nodo XAML e ripetere i passaggi.

Il flusso di nodi XAML fornito dai lettori XAML dei servizi XAML .NET offre sempre un attraversamento completo e profondo di tutti i nodi possibili. Le tecniche tipiche di controllo del flusso per un ciclo di nodi XAML includono la definizione di un corpo all'interno di while (reader.Read())e l'accensione di NodeType in ogni punto del nodo nel ciclo del nodo.

Se il flusso del nodo è alla fine del file, il nodo corrente è Null.

Il ciclo più semplice che usa un lettore e un writer è simile all'esempio seguente.

XamlXmlReader xxr = new XamlXmlReader(new StringReader(xamlStringToLoad));
//where xamlStringToLoad is a string of well formed XAML
XamlObjectWriter xow = new XamlObjectWriter(xxr.SchemaContext);
while (xxr.Read()) {
  xow.WriteNode(xxr);
}

Questo esempio di base di un ciclo di nodi XAML del percorso di caricamento connette in modo trasparente il lettore XAML e il writer XAML, facendo nulla di diverso da se fosse stato usato XamlServices.Parse. Ma questa struttura di base viene quindi espansa per applicare allo scenario di lettura o scrittura. Di seguito sono riportati alcuni scenari possibili:

  • Attivare NodeType. Eseguire azioni diverse a seconda del tipo di nodo da leggere.

  • Non chiamare WriteNode in tutti i casi. Solo chiamare WriteNode in alcuni casi NodeType.

  • All'interno della logica per un particolare tipo di nodo, analizzare le specifiche del nodo e agire su di esse. Ad esempio, è possibile scrivere solo oggetti provenienti da uno spazio dei nomi XAML specifico e quindi eliminare o rinviare oggetti non da tale spazio dei nomi XAML. Oppure è possibile eliminare o rielaborare qualsiasi direttiva XAML non supportata dal sistema XAML come parte dell'elaborazione dei membri.

  • Definire un XamlObjectWriter personalizzato che esegue l'override dei metodi Write*, possibilmente eseguendo il mapping dei tipi che ignora il contesto dello schema XAML.

  • Costruisci il XamlXmlReader per usare un contesto dello schema XAML non predefinito, in modo che le differenze personalizzate nel comportamento XAML vengano usate sia dal lettore che dal writer.

Accesso a XAML oltre il concetto di ciclo del nodo

Esistono potenzialmente altri modi per usare una rappresentazione XAML diversa da un ciclo di nodi XAML. Ad esempio, potrebbe esistere un lettore XAML in grado di leggere un nodo indicizzato o in particolare accede ai nodi direttamente da x:Name, x:Uido tramite altri identificatori. I servizi XAML .NET non forniscono un'implementazione completa, ma forniscono un modello suggerito tramite servizi e tipi di supporto. Per altre informazioni, vedere IXamlIndexingReader e XamlNodeList.

Uso del nodo corrente

La maggior parte degli scenari che usano un ciclo di nodi XAML non solo legge i nodi. La maggior parte degli scenari elabora i nodi correnti e passa ogni nodo uno alla volta a un'implementazione di XamlWriter.

Nello scenario tipico del percorso di caricamento, un XamlXmlReader produce un flusso di nodi XAML; i nodi XAML vengono elaborati in base alla logica e al contesto dello schema XAML; e i nodi vengono passati a un XamlObjectWriter. Si integra quindi l'oggetto grafico risultante nell'applicazione o nel framework.

In uno scenario tipico del percorso di salvataggio, un XamlObjectReader legge l'oggetto grafico, i singoli nodi XAML vengono elaborati e un XamlXmlWriter restituisce il risultato serializzato come file di testo XAML. La chiave è che entrambi i percorsi e gli scenari implicano l'uso di un solo nodo XAML alla volta e i nodi XAML sono disponibili per il trattamento in modo standardizzato definito dal sistema di tipi XAML e dalle API dei servizi XAML the.NET.

Frame e ambito

Un ciclo di nodi XAML illustra in modo lineare un flusso di nodi XAML. Il flusso del nodo attraversa oggetti, in membri che contengono altri oggetti e così via. Spesso è utile tenere traccia dell'ambito all'interno del flusso di nodi XAML implementando un concetto di frame e stack. Ciò è particolarmente vero se si modifica attivamente il flusso del nodo mentre ci si trova. Il supporto di frame e stack implementato come parte della logica del ciclo di nodi può contare StartObject (o GetObject) e EndObject ambiti mentre si scende in una struttura di nodi XAML se la struttura è considerata dal punto di vista DOM.

Attraversamento e immissione di nodi oggetto

Il primo nodo in un flusso di nodi quando viene aperto da un lettore XAML è il nodo dell'oggetto iniziale dell'oggetto radice. Per definizione, questo oggetto è sempre un singolo nodo oggetto e non ha peer. In qualsiasi esempio XAML reale, l'oggetto radice viene definito per avere una o più proprietà che contengono più oggetti e queste proprietà hanno nodi membro. I nodi membro hanno quindi uno o più nodi oggetto oppure possono anche terminare in un nodo valore. L'oggetto radice definisce in genere ambiti dei nomi XAML, assegnati sintatticamente come attributi nel markup di testo XAML, ma mappati a un tipo di nodo Namescope nella rappresentazione del flusso di nodi XAML.

Si consideri l'esempio XAML seguente (codice XAML arbitrario, non supportato da tipi esistenti in .NET). Si supponga che in questo modello a oggetti FavorCollection sia List<T> di Favor, Balloon e NoiseMaker siano assegnabili a Favor, la proprietà Balloon.Color è supportata da un oggetto Color simile al modo in cui WPF definisce i colori come nomi di colori noti e Color supporta un convertitore di tipi per la sintassi degli attributi.

Markup XAML Flusso di nodi XAML risultante
<Party nodo Namespace per Party
xmlns="PartyXamlNamespace"> nodo StartObject per Party
<Party.Favors> nodo StartMember per Party.Favors
nodo StartObject per l'FavorCollection implicito
StartMember nodo per la proprietà elementi FavorCollection implicita.
<Balloon nodo StartObject per Balloon
Color="Red" nodo StartMember per Color

Value nodo per la stringa del valore dell'attributo "Red"

EndMember per Color
HasHelium="True" nodo StartMember per HasHelium

Value nodo per la stringa del valore dell'attributo "True"

EndMember per HasHelium
> EndObject per Balloon
<NoiseMaker>Loudest</NoiseMaker> nodo StartObject per NoiseMaker

nodo StartMember per _Initialization

Value nodo per la stringa del valore di inizializzazione "Loudest"

nodo EndMember per _Initialization

EndObject per NoiseMaker
EndMember nodo per la proprietà elementi FavorCollection implicita.
nodo EndObject per l'FavorCollection implicito
</Party.Favors> EndMember per Favors
</Party> EndObject per Party

Nel flusso del nodo XAML puoi fare affidamento sul comportamento seguente:

  • Se esiste un nodo Namespace, viene aggiunto al flusso immediatamente prima del StartObject che ha dichiarato lo spazio dei nomi XAML con xmlns. Esaminare di nuovo la tabella precedente con il flusso di nodi XAML e di esempio. Si noti che i nodi StartObject e Namespace sembrano trasposti rispetto alle posizioni di dichiarazione nel markup di testo. Questo è rappresentativo del comportamento in cui i nodi dello spazio dei nomi vengono sempre visualizzati davanti al nodo a cui si applicano nel flusso del nodo. Lo scopo di questa progettazione è che le informazioni sullo spazio dei nomi sono fondamentali per gli autori di oggetti e devono essere note prima che il writer di oggetti tenti di eseguire il mapping dei tipi o elaborare in altro modo l'oggetto. L'inserimento delle informazioni sullo spazio dei nomi XAML prima dell'ambito dell'applicazione nel flusso rende più semplice elaborare sempre il flusso del nodo nell'ordine presentato.

  • A causa della considerazione precedente, si tratta di uno o più nodi Namespace letti per primi nella maggior parte dei casi di markup reali durante l'attraversamento dei nodi dall'inizio, non il StartObject della radice.

  • Un nodo StartObject può essere seguito da StartMember, Valueo da un EndObjectimmediato. Non viene mai seguito immediatamente da un altro StartObject.

  • Un StartMember può essere seguito da un StartObject, Valueo da un EndMemberimmediato . Può essere seguito da GetObject, per i membri in cui il valore deve provenire da un valore esistente dell'oggetto padre anziché da un StartObject che crea un'istanza di un nuovo valore. Può anche essere seguito da un nodo Namespace, che si applica a un prossimo StartObject. Non viene mai seguito immediatamente da un altro StartMember.

  • Un nodo Value rappresenta il valore stesso; non esiste "EndValue". Può essere seguito solo da un EndMember.

    • Il testo di inizializzazione XAML dell'oggetto come potrebbe essere usato dalla costruzione non comporta una struttura Object-Value. Viene invece creato un nodo membro dedicato per un membro denominato _Initialization. e il nodo membro contiene la stringa del valore di inizializzazione. Se esiste, _Initialization è sempre il primo StartMember. _Initialization possono essere qualificati in alcune rappresentazioni di servizi XAML con l'ambito dei nomi XAML del linguaggio XAML, per chiarire che _Initialization non è una proprietà definita nei tipi di supporto.

    • Una combinazione di Member-Value rappresenta un'impostazione dell'attributo del valore. Potrebbe essere presente un convertitore di valori coinvolto nell'elaborazione di questo valore e il valore è una stringa normale. Tuttavia, questa operazione non viene valutata fino a quando un writer di oggetti XAML non elabora questo flusso di nodi. Il writer di oggetti XAML possiede il contesto dello schema XAML necessario, il mapping del sistema dei tipi e altro supporto necessario per le conversioni di valori.

  • Un nodo EndMember può essere seguito da un nodo StartMember per un membro successivo o da un nodo EndObject per il proprietario del membro.

  • Un nodo EndObject può essere seguito da un nodo EndMember. Può anche essere seguito da un nodo StartObject nei casi in cui gli oggetti sono peer negli elementi di una raccolta. In alternativa, può essere seguito da un nodo Namespace, che si applica a un prossimo StartObject.

    • Per il caso univoco di chiusura dell'intero flusso del nodo, il EndObject della radice non è seguito da nulla; il lettore è ora la fine del file e Read restituisce false.

Convertitori di valori e flusso del nodo XAML

Un convertitore di valori è un termine generale per un'estensione di markup, un convertitore di tipi (inclusi serializzatori di valori) o un'altra classe dedicata segnalata come convertitore di valori tramite il sistema di tipi XAML. Nel flusso del nodo XAML, l'utilizzo di un convertitore di tipi e l'utilizzo di un'estensione di markup hanno rappresentazioni molto diverse.

Convertitori di tipi nel flusso del nodo XAML

Un set di attributi che alla fine genera un utilizzo del convertitore di tipi viene segnalato nel flusso del nodo XAML come valore di un membro. Il flusso di nodi XAML non tenta di produrre un oggetto istanza del convertitore di tipi e di passarvi il valore. L'uso dell'implementazione della conversione di un convertitore di tipi richiede richiamare il contesto dello schema XAML e usarlo per il mapping dei tipi. Anche determinare quale classe convertitore di tipi deve essere usata per elaborare il valore richiede indirettamente il contesto dello schema XAML. Quando usi il contesto dello schema XAML predefinito, queste informazioni sono disponibili nel sistema dei tipi XAML. Se hai bisogno delle informazioni sulla classe del convertitore di tipi a livello di flusso del nodo XAML prima della connessione a un writer XAML, puoi ottenerle dalle informazioni XamlMember del membro da impostare. In caso contrario, l'input del convertitore di tipi deve essere mantenuto nel flusso del nodo XAML come valore normale fino al resto delle operazioni che richiedono l'esecuzione del sistema di mapping dei tipi e del contesto dello schema XAML, ad esempio la creazione dell'oggetto da parte di un writer di oggetti XAML.

Si consideri, ad esempio, la struttura della definizione della classe seguente e l'utilizzo xaml per questo tipo:

public class BoardSizeConverter : TypeConverter {
  //converts from string to an int[2] by splitting on an "x" char
}
public class GameBoard {
  [TypeConverter(typeof(BoardSizeConverter))]
  public int[] BoardSize; //2x2 array, initialization not shown
}
<GameBoard BoardSize="8x8"/>

Una rappresentazione testuale del flusso di nodi XAML per questo utilizzo può essere espressa come segue:

StartObject con XamlType che rappresenta GameBoard

StartMember con XamlMember che rappresenta BoardSize

Value nodo con stringa di testo "8x8"

EndMember corrisponde BoardSize

EndObject corrisponde GameBoard

Si noti che non esiste alcuna istanza del convertitore di tipi in questo flusso di nodi. Tuttavia, è possibile ottenere informazioni sul convertitore di tipi chiamando XamlMember.TypeConverter sul XamlMember per BoardSize. Se si dispone di un contesto di schema XAML valido, è anche possibile richiamare i metodi del convertitore ottenendo un'istanza da ConverterInstance.

Estensioni di markup nel flusso del nodo XAML

Un utilizzo dell'estensione di markup viene segnalato nel flusso del nodo XAML come nodo oggetto all'interno di un membro, dove l'oggetto rappresenta un'istanza dell'estensione di markup. Pertanto, un utilizzo dell'estensione di markup viene presentato in modo più esplicito nella rappresentazione del flusso di nodi rispetto all'utilizzo di un convertitore di tipi e contiene altre informazioni. XamlMember informazioni non potevano aver detto nulla sull'estensione di markup, perché l'utilizzo è situazionele e varia in ogni caso di markup possibile; non è dedicato e implicito per tipo o membro, come nel caso dei convertitori di tipi.

La rappresentazione del flusso di nodi delle estensioni di markup come nodi oggetto è il caso anche se l'utilizzo dell'estensione di markup è stato effettuato in formato attributo nel markup di testo XAML (che spesso è il caso). Gli utilizzi delle estensioni di markup che utilizzavano un modulo di elemento oggetto esplicito vengono trattati allo stesso modo.

All'interno di un nodo dell'oggetto estensione di markup possono essere presenti membri dell'estensione di markup. La rappresentazione del flusso del nodo XAML mantiene l'utilizzo di tale estensione di markup, sia che si tratti di un utilizzo di parametri posizionali o di un utilizzo con parametri denominati espliciti.

Per l'utilizzo di un parametro posizionale, il flusso del nodo XAML contiene una proprietà definita dal linguaggio XAML _PositionalParameters che registra l'utilizzo. Questa proprietà è una List<T> generica con vincolo Object. Il vincolo è un oggetto e non una stringa perché un utilizzo di parametri posizionali può contenere utilizzi di estensioni di markup annidate al suo interno. Per accedere ai parametri posizionali dall'utilizzo, è possibile scorrere l'elenco e usare gli indicizzatori per i singoli valori di elenco.

Per l'utilizzo di un parametro denominato, ogni parametro denominato viene rappresentato come nodo membro di tale nome nel flusso del nodo. I valori dei membri non sono necessariamente stringhe, perché potrebbe essere presente un utilizzo dell'estensione di markup annidato.

ProvideValue dall'estensione di markup non viene ancora richiamato. Viene tuttavia richiamato se si connette un lettore XAML e un writer XAML in modo che WriteEndObject venga richiamato nel nodo dell'estensione di markup quando lo si esamina nel flusso del nodo. Per questo motivo, in genere è necessario lo stesso contesto dello schema XAML disponibile per formare l'oggetto grafico nel percorso di caricamento. In caso contrario, ProvideValue da qualsiasi estensione di markup può generare eccezioni, perché non dispone di servizi previsti disponibili.

Membri Language-Defined XAML e XML nel flusso del nodo XAML

Alcuni membri vengono introdotti in un flusso di nodi XAML a causa di interpretazioni e convenzioni di un lettore XAML, anziché tramite un XamlMember esplicito ricerca o costruzione. Spesso, questi membri sono direttive XAML. In alcuni casi, è l'atto di leggere il codice XAML che introduce la direttiva nel flusso del nodo XAML. In altre parole, il testo XAML di input originale non specifica in modo esplicito la direttiva membro, ma il lettore XAML inserisce la direttiva per soddisfare una convenzione XAML strutturale e segnalare le informazioni nel flusso del nodo XAML prima che tali informazioni vengano perse.

L'elenco seguente annota tutti i casi in cui un lettore XAML dovrebbe introdurre un nodo membro XAML di direttiva e come tale nodo membro viene identificato nelle implementazioni dei servizi XAML .NET.

  • testo di inizializzazione per un nodo oggetto: Il nome di questo nodo membro è _Initialization, rappresenta una direttiva XAML e viene definita nello spazio dei nomi XAML del linguaggio XAML. È possibile ottenere un'entità statica da Initialization.

  • parametri posizionali per un'estensione di markup: Il nome di questo nodo membro è _PositionalParameterse viene definito nello spazio dei nomi XAML del linguaggio XAML. Contiene sempre un elenco generico di oggetti, ognuno dei quali è un parametro posizionale pre-separato dividendo sul carattere delimitatore , fornito nel codice XAML di input. È possibile ottenere un'entità statica per la direttiva dei parametri posizionali da PositionalParameters.

  • Contenuto sconosciuto: Il nome del nodo membro è _UnknownContent. In senso stretto, si tratta di un XamlDirectivee viene definito nello spazio dei nomi XAML del linguaggio XAML. Questa direttiva viene usata come sentinel per i casi in cui un elemento oggetto XAML contiene contenuto nel codice XAML di origine, ma non è possibile determinare alcuna proprietà di contenuto nel contesto dello schema XAML attualmente disponibile. È possibile rilevare questo caso in un flusso di nodi XAML controllando la presenza di membri denominati _UnknownContent. Se non viene eseguita alcuna altra azione in un flusso di nodi XAML del percorso di caricamento, il XamlObjectWriter predefinito genera un'eccezione durante il tentativo di WriteEndObject quando rileva il membro _UnknownContent su qualsiasi oggetto. Il XamlXmlWriter predefinito non genera e considera il membro come implicito. È possibile ottenere un'entità statica per _UnknownContent da UnknownContent.

  • proprietà Collection di una raccolta: Sebbene il tipo CLR di supporto di una classe di raccolta usata per XAML abbia in genere una proprietà denominata dedicata che contiene gli elementi della raccolta, tale proprietà non è nota a un sistema di tipi XAML prima di eseguire il backup della risoluzione dei tipi. Il flusso del nodo XAML introduce invece un segnaposto Items come membro del tipo XAML della raccolta. Nell'implementazione dei servizi XAML .NET il nome di questa direttiva o membro nel flusso del nodo è _Items. Una costante per questa direttiva può essere ottenuta da Items.

    Si noti che un flusso di nodi XAML potrebbe contenere una proprietà Items con elementi che si rivelano non analizzabili in base alla risoluzione del tipo di supporto e al contesto dello schema XAML. Per esempio

  • membri definiti da XML: I membri xml:basedefiniti da XML, xml:lang e xml:space vengono segnalati come direttive XAML denominate base, lange space nelle implementazioni dei servizi XAML .NET. Lo spazio dei nomi per questi è lo spazio dei nomi XML http://www.w3.org/XML/1998/namespace. Le costanti per ognuna di queste costanti possono essere ottenute da XamlLanguage.

Ordine dei nodi

In alcuni casi, XamlXmlReader modifica l'ordine dei nodi XAML nel flusso di nodi XAML, rispetto all'ordine in cui i nodi vengono visualizzati nel markup o se elaborati come XML. Questa operazione viene eseguita per ordinare i nodi in modo che un XamlObjectWriter possa elaborare il flusso del nodo in modo forward-only. Nei servizi XAML .NET il lettore XAML riordina i nodi invece di lasciare questa attività al writer XAML, come ottimizzazione delle prestazioni per i consumer di writer di oggetti XAML del flusso di nodi.

Alcune direttive sono destinate specificamente a fornire ulteriori informazioni per la creazione di un oggetto da un elemento oggetto. Queste direttive sono: Initialization, PositionalParameters, TypeArguments, FactoryMethod, Arguments. I lettori XAML dei servizi XAML .NET tentano di inserire queste direttive come primi membri nel flusso del nodo dopo l'StartObjectdi un oggetto , per motivi illustrati nella sezione successiva.

Comportamento xamlObjectWriter e ordine dei nodi

StartObject a un XamlObjectWriter non è necessariamente un segnale al writer di oggetti XAML per costruire immediatamente l'istanza dell'oggetto. XAML include diverse funzionalità del linguaggio che consentono di inizializzare un oggetto con input aggiuntivo e di non basarsi interamente sulla chiamata di un costruttore senza parametri per produrre l'oggetto iniziale e solo successivamente impostando le proprietà. Queste funzionalità includono: ; testo di inizializzazione; x:TypeArguments; parametri posizionali di un'estensione di markup; metodi factory e nodi x:Arguments (XAML 2009). Ognuno di questi casi ritarda la costruzione effettiva dell'oggetto e poiché il flusso del nodo viene riordinato, il writer di oggetti XAML può basarsi su un comportamento di costruzione effettiva dell'istanza ogni volta che viene rilevato un membro iniziale che non è specificamente una direttiva di costruzione per quel tipo di oggetto.

GetObject

GetObject rappresenta un nodo XAML in cui anziché costruire un nuovo oggetto, un writer di oggetti XAML deve invece ottenere il valore della proprietà contenitore dell'oggetto. Un caso tipico in cui viene rilevato un nodo GetObject in un flusso di nodi XAML riguarda un oggetto raccolta o un oggetto dizionario, quando la proprietà contenitore è deliberatamente di sola lettura nel modello a oggetti del tipo di supporto. In questo scenario, la raccolta o il dizionario spesso viene creato e inizializzato (in genere vuoto) dalla logica di inizializzazione di un tipo proprietario.

Vedere anche