Condividi tramite


Estensioni di markup e XAML

Aggiornamento: novembre 2007

In questo argomento viene introdotto il concetto di estensioni di markup per Extensible Application Markup Language (XAML), incluse le regole di sintassi, lo scopo e il modello a oggetti delle classi sottostante.

Nel presente argomento sono contenute le seguenti sezioni.

  • Processori XAML ed estensioni di markup
  • Sintassi delle estensioni di markup di base
  • Estensioni di markup specifiche di WPF
  • Estensioni di markup definite da XAML
  • Ulteriori informazioni sulla sintassi delle estensioni di markup
  • Argomenti correlati

Processori XAML ed estensioni di markup

Per processore XAML si intende qualsiasi programma che può accettare XAML come linguaggio secondo le proprie specifiche (tramite compilazione o interpretazione) e può produrre le classi sottostanti che ne risultano per utilizzarle in un modello a oggetti di runtime (secondo le specifiche XAML ). Per impostazione predefinita, tale processore interpreterà un valore di attributo come stringa letterale o lo convertirà in un oggetto in base al tipo dell'attributo o ai convertitori di tipi specifici per tale attributo. Tuttavia, vi sono alcuni scenari in cui è necessario un comportamento diverso. Ad esempio, è possibile indicare a un processore XAML che un valore di un attributo deve essere invece un riferimento a un oggetto già costruito o a un oggetto statico. In un altro scenario, è possibile impostare un processore XAML affinché utilizzi una sintassi che fornisce argomenti non predefiniti al costruttore di un oggetto, un'aberrazione dal comportamento predefinito del processore XAML specificato.

Sintassi delle estensioni di markup di base

È possibile implementare un'estensione di markup per fornire valori per le proprietà nell'utilizzo di un attributo, per le proprietà nell'utilizzo di un elemento proprietà o in entrambi i casi.

Quando viene utilizzata per fornire un valore di attributo, la sintassi che distingue un'estensione di markup in un processore XAML è la presenza delle parentesi graffe di apertura e chiusura ({ e }). Il tipo di estensione di markup viene quindi identificato tramite il token di stringa immediatamente successivo alla parentesi graffa di apertura.

Quando viene utilizzata nella sintassi degli elementi proprietà, un'estensione di markup corrisponde visivamente a qualsiasi altro elemento utilizzato per fornire un valore di elemento proprietà, ovvero una dichiarazione di elementi XAML che fa riferimento alla classe dell'estensione di markup come elemento, racchiuso tra parentesi angolari (<>).

Estensioni di markup specifiche di WPF

Le estensioni di markup più comuni utilizzate nella programmazione WPF sono quelle che supportano riferimenti alle risorse (StaticResource e DynamicResource) e quelle che supportano l'associazione dati (Binding).

StaticResource fornisce un valore per una proprietà XAML sostituendo il valore di una risorsa già definita. Per informazioni dettagliate, vedere Estensione del markup StaticResource.

DynamicResource fornisce un valore per una proprietà XAML rinviando tale valore come riferimento di runtime a una risorsa. Un riferimento a una risorsa dinamica impone una nuova ricerca ogni volta che si accede a tale risorsa. Per informazioni dettagliate, vedere Estensione del markup DynamicResource.

Binding fornisce un valore associato a dati per una proprietà, in base al contesto dati che si applica all'elemento. Questa estensione di markup è relativamente complessa, poiché attiva una sintassi inline sostanziale per la specifica di un'associazione dati. Per informazioni dettagliate, vedere Associazione dell'estensione di markup.

RelativeSource fornisce informazioni di origine per un oggetto Binding che può passare tra diverse relazioni possibili nella struttura ad albero degli elementi di runtime. Vengono in tal modo fornite origini specializzate per le associazioni create nei modelli multiuso o nel codice senza una conoscenza approfondita della struttura ad albero degli elementi circostanti. Per informazioni dettagliate, vedere Estensione del markup RelativeSource.

Con TemplateBinding, un modello di controllo può utilizzare valori per proprietà basate su modelli che provengono da proprietà definite sul modello a oggetti della classe che utilizzerà il modello. Per informazioni dettagliate, vedere Estensione del markup TemplateBinding. Per ulteriori informazioni sull'utilizzo pratico di TemplateBinding, vedere Esempio di applicazione di stili con ControlTemplate.

Estensioni di markup definite da XAML

Sono disponibili varie estensioni di markup che non sono specifiche dell'applicazione WPF di XAML, ma fanno invece parte della specifica di XAML come linguaggio. In genere, queste estensioni sono identificabili dal prefisso x: nella sintassi come illustrato nell'utilizzo comune. L'implementazione WPF per questi elementi del linguaggio utilizza la stessa classe di base MarkupExtension per l'implementazione.

Nota

Il prefisso x: viene utilizzato per il mapping tipico dello spazio dei nomi XML di XAML, nell'elemento radice di un'applicazione o di un documento XAML. Ad esempio, nei modelli Microsoft Visual Studio 2005 un file XAML viene avviato utilizzando questo mapping x:. È possibile scegliere un token di prefisso diverso nel mapping dello spazio dei nomi XML personalizzato, ma in questa documentazione viene utilizzato il mapping x: predefinito come mezzo per identificare le entità che rappresentano una parte definita dello spazio dei nomi XAML, rispetto allo spazio dei nomi WPF o ad altri spazi dei nomi CLR o XML arbitrari.

x:Type fornisce l'oggetto Type per il tipo denominato. Tale oggetto viene utilizzato più frequentemente in stili e modelli. Per informazioni dettagliate, vedere Estensione del markup x:Type.

x:Static produce valori statici da entità di codice di tipo di valore che non sono direttamente il tipo del valore di una proprietà, ma possono essere valutate in base a tale tipo. Per informazioni dettagliate, vedere Estensione del markup x:Static.

x:Null specifica null come valore per una proprietà XAML. Per informazioni dettagliate, vedere Estensione del markup x:Null.

x:Array offre supporto per la creazione di matrici generali nella sintassi XAML, per i casi in cui si sceglie intenzionalmente di non utilizzare il supporto degli insiemi fornito dagli elementi di base e dai modelli di controllo. Per informazioni dettagliate, vedere Estensione del markup x:Array.

Ulteriori informazioni sulla sintassi delle estensioni di markup

*Classi di estensione

Il comportamento di ogni estensione di markup viene identificato in un processore XAML tramite una *classe di estensione che deriva da MarkupExtension e fornisce un'implementazione del metodo ProvideValue. Questo metodo definisce su ogni estensione l'oggetto che viene restituito dopo la valutazione dell'estensione di markup. In genere, viene creata un'istanza dell'oggetto restituito oppure l'oggetto viene impostato utilizzando i vari token di stringa passati all'estensione di markup.

Ad esempio, la classe StaticResourceExtension fornisce l'implementazione di superficie della ricerca effettiva di risorse in modo che l'implementazione ProvideValue restituisca l'oggetto richiesto, con l'input di tale implementazione costituito da una stringa utilizzata per cercare la risorsa in base al proprio x:Key. Molti dettagli di questa implementazione non sono importanti se si utilizza un'estensione di markup esistente.

Interpretazione dei token di stringa successivi nelle classi di estensione

I token di stringa che seguono l'identificatore dell'estensione di markup e si trovano all'interno delle parentesi graffe sono interpretati da un processore XAML in uno dei modi seguenti:

  • Una virgola rappresenta sempre il separatore o il delimitatore di token singoli. Non è pertanto possibile passare una virgola letterale a un'estensione di markup.

  • Se i singoli token separati non contengono segni di uguale, ogni token viene trattato come un argomento del costruttore. Ogni parametro del costruttore deve essere fornito come il tipo previsto dalla firma e nell'ordine corretto previsto dalla firma.

    Nota

    Un processore XAML deve chiamare il costruttore che corrisponde al conteggio di argomenti del numero di coppie. Per questo motivo, se si implementa un'estensione di markup personalizzata, non fornire più parametri con lo stesso conteggio di argomenti. Il comportamento per i casi in cui sono presenti più costruttori dell'estensione di markup con lo stesso conteggio di parametri non è definito.

  • Se i singoli token separati contengono segni di uguale, un processore XAML chiama innanzitutto il costruttore predefinito per l'estensione di markup. Quindi, ogni coppia nome=valore viene interpretata come nome di proprietà presente nell'estensione di markup e come valore da assegnare a tale proprietà.

  • Se in un'estensione di markup è presente un risultato parallelo tra il comportamento del costruttore e il comportamento dell'impostazione delle proprietà, il comportamento utilizzato è ininfluente. È più comune utilizzare coppie proprietà=valore per estensioni di markup che presentano più proprietà impostabili, anche perché con questa soluzione il markup è più intenzionale ed è meno probabile che si traspongano accidentalmente parametri del costruttore (quando si specificano coppie proprietà=valore, è possibile utilizzare un ordine qualsiasi per le proprietà). Inoltre, non vi è garanzia che un'estensione di markup fornisca un parametro del costruttore che imposti ciascuna delle proprietà impostabili. Ad esempio, Binding è un'estensione di markup, con molte proprietà impostabili tramite l'estensione nel formato proprietà=valore, ma Binding supporta solo due costruttori: un costruttore predefinito e uno che imposta un percorso iniziale.

Caratteri di escape per le parentesi graffe letterali

Nella gestione degli attributi in un processore XAML vengono utilizzate le parentesi graffe come indicatori di un'estensione di markup. Se necessario, è anche possibile produrre un valore di attributo letterale per i caratteri di parentesi graffe, immettendo una sequenza di escape tramite una coppia di parentesi graffe vuota seguita dalla parentesi graffa letterale. Vedere Sequenza di escape/Estensione di markup {}.

Nidificazione della sintassi delle estensioni

La nidificazione di più estensioni di markup è supportata. Ogni estensione di markup viene innanzitutto valutata al livello più profondo, ad esempio:

<Setter Property="Background"

Value="{DynamicResource {x:Static SystemColors.ControlBrushKey}}" />

Ulteriori informazioni sulle estensioni di markup e sulla sintassi degli elementi delle proprietà

Se una classe di estensione di markup viene utilizzata come elemento oggetto che riempie il valore di un elemento proprietà, non è possibile distinguerla a livello visivo da un elemento comune che può essere utilizzato in XAML. La differenza pratica tra un elemento comune e un'estensione di markup in questa circostanza consiste nel fatto che l'estensione di markup viene valutata su un valore tipizzato o rinviata come espressione, pertanto i meccanismi per eventuali errori di tipo possibili dei valori della proprietà saranno diversi, simili alla modalità di utilizzo di una proprietà ad associazione tardiva in altri modelli di programmazione. Un elemento comune verrà valutato per il tipo rispetto alla proprietà che imposta immediatamente in fase di compilazione.

La maggior parte delle estensioni di markup, se utilizzate nella sintassi di elementi oggetto per riempire un elemento proprietà, non avrà contenuto o altra sintassi degli elementi proprietà all'interno, consentendo così di chiudere il tag dell'elemento oggetto senza fornire elementi figlio. Ogni volta che viene rilevato un elemento oggetto da un processore XAML, il costruttore per tale classe viene chiamato per creare un'istanza dell'oggetto creato dall'elemento analizzato. Una classe di estensione di markup non è diversa; se pertanto si desidera che l'estensione di markup sia utilizzabile nella sintassi degli elementi oggetto, è necessario fornire un costruttore predefinito. Alcune estensioni di markup esistenti hanno almeno un valore di proprietà obbligatorio che è necessario specificare per un'inizializzazione efficace. In tal caso, il valore di tale proprietà viene generalmente fornito come attributo di proprietà sull'elemento oggetto. Nelle pagine di riferimento su Funzionalità del linguaggio dello spazio dei nomi XAML (x:) e Estensioni XAML degli spazi dei nomi WPF sono indicate le estensioni di markup che presentano proprietà obbligatorie, con i nomi di tali proprietà. Nelle pagine di riferimento viene inoltre indicato se la sintassi degli elementi oggetto o la sintassi degli attributi non è consentita per determinate estensioni di markup. Un caso da tenere presente è Estensione del markup x:Array, che non può supportare la sintassi degli attributi poiché è necessario specificare il contenuto di tale matrice. Il contenuto delle matrici è gestito come oggetto generico, pertanto non è possibile applicare alcun convertitore di tipi predefinito per l'attributo. Inoltre, Estensione del markup x:Array richiede un parametro Type.

Vedere anche

Concetti

Cenni preliminari su XAML

Riferimenti

Estensione del markup StaticResource

Associazione dell'estensione di markup

Estensione del markup DynamicResource

Estensione del markup x:Type

Altre risorse

Funzionalità del linguaggio dello spazio dei nomi XAML (x:)

Estensioni XAML degli spazi dei nomi WPF