Share via


Terminologia della sintassi XAML

Aggiornamento: novembre 2007

In questo argomento vengono definiti i termini utilizzati per descrivere gli elementi della sintassi Extensible Application Markup Language (XAML). Questi termini sono utilizzati frequentemente nelle restanti sezioni di questo Software Development Kit (SDK). In questo argomento viene utilizzata la terminologia di base presentata nella sezione Cenni preliminari su XAML.

Nel presente argomento sono contenute le seguenti sezioni.

  • Origine della terminologia della sintassi XAML
  • Sintassi degli elementi oggetto
  • Sintassi degli attributi
  • Sintassi degli elementi proprietà
  • Sintassi del contenuto XAML
  • Proprietà associate
  • Eventi associati
  • Spazi dei nomi Xml
  • Estensioni di markup
  • Utilizzi facoltativi e non consigliati di XAML
  • Argomenti correlati

Origine della terminologia della sintassi XAML

La terminologia della sintassi XAML presentata in questo argomento è anche definita o riportata nella specifica del linguaggio XAML. XAML è un linguaggio basato su XML e sulle regole strutturali del linguaggio XML. Parte della terminologia si fonda sulla terminologia comunemente utilizzata quando si descrive il linguaggio XML o XML DOM (Document Object Model).

Sintassi degli elementi oggetto

La sintassi degli elementi oggetto è la sintassi del markup XAML che crea un'istanza di una classe o di una struttura Common Language Runtime (CLR) dichiarando un elemento XML. Questa sintassi è simile alla sintassi degli elementi di altri linguaggi di markup, ad esempio HTML. La sintassi degli elementi oggetto inizia con una parentesi angolare aperta (<), seguita immediatamente dal nome del tipo della classe o della struttura di cui viene creata un'istanza. Il nome del tipo può essere seguito da zero o più spazi ed è inoltre possibile dichiarare zero o più attributi nell'elemento oggetto, con uno o più spazi che separano ciascuna coppia nome="valore" dell'attributo. Infine, una delle seguenti condizioni deve essere soddisfatta:

  • L'elemento e il tag devono essere chiusi da una barra (/) seguita immediatamente da una parentesi angolare chiusa (>).

  • Il tag di apertura deve essere completato da una parentesi angolare chiusa (>). Altri elementi oggetto, elementi proprietà o il testo interno possono seguire il tag di apertura. Il contenuto esatto che è possibile inserire qui è generalmente vincolato dal modello a oggetti dell'elemento; vedere la sezione "Sintassi del contenuto" in questo argomento. Deve inoltre essere presente il tag di chiusura equivalente per l'elemento oggetto, opportunamente nidificato e bilanciato con l'altra coppia di tag di apertura e chiusura.

Nell'esempio riportato di seguito viene illustrata la sintassi dell'elemento oggetto tramite cui viene creata una nuova istanza della classe Button e viene specificato un attributo Name e un valore per tale attributo:

<Button Name="CheckoutButton"/>

Nell'esempio riportato di seguito viene illustrata la sintassi dell'elemento oggetto che include anche la sintassi delle proprietà del contenuto Extensible Application Markup Language (XAML). Il testo interno contenuto verrà utilizzato per impostare la proprietà di contenuto Extensible Application Markup Language (XAML) di TextBox, Text.

<TextBox>This is a Text Box</TextBox>

Sintassi degli attributi

La sintassi degli attributi è la sintassi del markup XAML mediante cui viene impostato un valore per una proprietà o viene denominato un gestore eventi per un evento, dichiarando un attributo in un elemento. L'elemento viene sempre dichiarato attraverso la sintassi degli elementi oggetto. Il nome dell'attributo deve corrispondere al nome del membro CLR di una proprietà o di un evento. Il nome dell'attributo è seguito da un operatore di assegnazione (=). Il valore dell'attributo deve essere una stringa racchiusa tra due virgolette doppie (").

Per consentirne l'impostazione tramite la sintassi degli attributi, è necessario che una proprietà sia pubblica e di lettura/scrittura e che disponga di un tipo di valore di proprietà di cui può essere creata un'istanza o a cui è possibile fare riferimento mediante un processore XAML. È inoltre necessario che l'evento sia pubblico e disponga di un delegato pubblico. La proprietà o l'evento deve essere un membro della classe o della struttura di cui viene creata un'istanza da parte dell'elemento oggetto contenitore.

Il valore di attributo viene riempito da uno degli elementi riportati di seguito, utilizzando questo ordine di elaborazione:

  1. Se il processore XAML rileva una parentesi graffa o un elemento oggetto che deriva da MarkupExtension, l'estensione del markup a cui si fa riferimento viene prima valutata anziché elaborata come stringa e viene utilizzato l'oggetto restituito dall'estensione del markup. In molti casi l'oggetto restituito da un'estensione del markup sarà un riferimento a un oggetto esistente o un'espressione che rinvia la valutazione alla fase di esecuzione, non un oggetto nuovo.

  2. Se la proprietà viene dichiarata con un oggetto TypeConverter designato o il tipo di valore di tale proprietà viene dichiarato con un oggetto TypeConverter con attributi, il valore di stringa dell'attributo viene inviato al convertitore di tipi come input di conversione e una nuova istanza dell'oggetto viene restituita dal convertitore.

  3. Se non è presente alcun oggetto TypeConverter, viene tentata una conversione diretta al tipo della proprietà. Questo livello finale rappresenta una conversione diretta tra tipi primitivi o una ricerca di nomi in un'enumerazione (tramite cui vengono restituiti i valori corrispondenti).

Ad esempio, utilizzando lo stesso markup indicato in precedenza, nell'esempio riportato di seguito viene illustrata la sintassi degli attributi utilizzata per assegnare un valore di stringa alla proprietà Name:

<Button Name="CheckoutButton"/>

La proprietà Name è un membro della tabella dei membri per la classe Button. Button è una classe derivata della classe FrameworkElement che definisce Name.

Elaborazione dei valori di attributo

Il valore di stringa racchiuso tra le virgolette di apertura e chiusura viene elaborato da un processore XAML. Per le proprietà, il comportamento di elaborazione predefinito è determinato dal tipo della proprietà CLR sottostante. Se la proprietà è un tipo primitivo, il valore di attributo viene assegnato in base alla conversione implicita della stringa nel tipo primitivo rilevante. Se la proprietà è un'enumerazione, la stringa viene considerata come un nome definito da tale enumerazione e viene restituito il valore corrispondente dell'enumerazione. Se la proprietà non è un tipo primitivo o un'enumerazione, il valore di attributo deve essere gestito da un convertitore di tipi dichiarato nella proprietà stessa o nel tipo di destinazione. Il convertitore di tipi deve fornire una conversione che accetta una stringa e deve restituire un'istanza del tipo della proprietà CLR sottostante. Il passaggio di conversione potrebbe anche essere rinviato tramite un'estensione di markup.

Valori di attributo dell'enumerazione

I valori di enumerazione in XAML vengono elaborati in modo intrinseco dai metodi nativi della struttura Enum.

Per i valori di enumerazione non flag, il comportamento nativo consiste nell'elaborare la stringa di un valore di attributo e risolverla in uno dei valori di enumerazione. L'enumerazione non viene specificata nel formato Enumerazione.Valore, come avviene nel codice. Viene invece specificato solo Valore, mentre Enumerazione viene dedotta dal tipo della proprietà che si sta impostando. Se si specifica un attributo nel formato Enumerazione.Valore, non verrà risolto correttamente.

Per le enumerazioni basate su flag, il comportamento è basato sul metodo Enum.Parse. È possibile specificare più valori per un'enumerazione basata su flag separando ogni valore con una virgola. Tuttavia, non è possibile combinare valori di enumerazione non basati su flag. Ad esempio, non è possibile utilizzare la sintassi della virgola per tentare di creare un oggetto Trigger utilizzabile su più condizioni di un'enumerazione non flag:

<!--This will not compile, because Visibility is not a flagwise enumeration.-->
...
<Trigger Property="Visibility" Value="Collapsed,Hidden">
  <Setter ... />
</Trigger>
...

Le enumerazioni basate su flag che supportano attributi impostabili in XAML sono rare in WPF. Tuttavia, StyleSimulations è un'enumerazione di questo tipo. Ad esempio, è possibile utilizzare la sintassi degli attributi basata su flag e delimitata da virgole per modificare l'esempio illustrato nelle Osservazioni per la classe Glyphs; StyleSimulations = "BoldSimulation" può diventare StyleSimulations = "BoldSimulation,ItalicSimulation". KeyBinding.Modifiers è un’altra proprietà in cui è possibile specificare più di un valore di enumerazione. Tuttavia, questa proprietà è un caso speciale, perché l'enumerazione ModifierKeys supporta il proprio convertitore di tipi. Il convertitore di tipi per i modificatori utilizza un segno più (+) come delimitatore, anziché una virgola (,), in modo tale che la sintassi più tradizionale per rappresentare le combinazioni di tasti, ad esempio "CTRL+ALT", sia supportata nel markup.

Riferimenti ai nomi dei membri di eventi e proprietà

Quando si specifica un attributo, è possibile fare riferimento a qualsiasi proprietà o evento esistente come membro del tipo CLR di cui è stata creata un'istanza per l'elemento oggetto contenitore.

In alternativa, è possibile fare riferimento a una proprietà associata o a un evento associato, indipendente dall'elemento oggetto contenitore.

È anche possibile denominare qualsiasi evento di qualsiasi oggetto accessibile tramite lo spazio dei nomi predefinito utilizzando un nome parzialmente qualificato nomeTipo.evento; questa sintassi supporta l'associazione di gestori per eventi indirizzati dove il gestore ha lo scopo di gestire un evento indirizzato da elementi figlio, ma nella tabella dei membri dell'elemento padre tale evento non è presente. Questa sintassi è simile alla sintassi di un evento associato, benché qui l'evento non sia un evento associato effettivo. In realtà, si fa riferimento a un evento con un nome completo. Per ulteriori informazioni, vedere Cenni preliminari sugli eventi indirizzati.

In alcuni casi i nomi delle proprietà vengono forniti come valore di un attributo, anziché come nome di attributo, e tale nome di proprietà può includere anche qualificatori, ad esempio la proprietà specificata nel formato tipoProprietario.nomeProprietàDipendenza. Questo scenario è comune quando si scrivono stili o modelli in XAML. Le regole di elaborazione per i nomi delle proprietà forniti come valore di attributo sono diverse e dipendono dal tipo della proprietà impostata e da alcuni fattori di contesto, ad esempio l'eventuale presenza di un tipo di destinazione per uno stile o un modello. Per informazioni dettagliate, vedere Applicazione di stili e modelli.

Un altro utilizzo per i nomi delle proprietà è rappresentato dal caso in cui un valore di attributo descrive una relazione proprietà-proprietà. Questa funzionalità viene utilizzata per l'associazione dati e per le destinazioni di storyboard e viene attivata dalla classe PropertyPath e dal relativo convertitore di tipo. Per una descrizione più completa della semantica di ricerca, vedere Sintassi XAML di PropertyPath.

Sintassi degli elementi proprietà

La sintassi degli elementi proprietà si differenzia per certi versi dalla sintassi XML di base. In XML, il valore di un attributo è una stringa di fatto, con la sola possibile variazione rappresentata dal formato di codifica della stringa utilizzato. In XAML, è possibile assegnare altri elementi oggetto come valore di una proprietà. Questa funzionalità viene attivata dalla sintassi degli elementi proprietà. Anziché essere specificata come un attributo all'interno del tag di elemento, la proprietà viene specificata utilizzando un tag di elemento di apertura nel formato nomeTipoElemento.nomeProprietà, viene specificato il valore della proprietà, quindi viene chiuso l'elemento proprietà.

In particolare, la sintassi inizia con una parentesi angolare aperta (<), seguita immediatamente dal nome del tipo della classe o della struttura in cui è contenuta la sintassi degli elementi proprietà. Questo è seguito da un punto singolo (.), dal nome di una proprietà che deve essere presente all'interno della tabella dei membri del tipo specificato, quindi da una parentesi angolare chiusa (>). Il valore da assegnare alla proprietà è contenuto nell’elemento proprietà. In genere, il valore viene fornito come uno o più elementi oggetto, poiché la specifica di oggetti come valori rappresenta lo scenario per il quale la sintassi degli elementi proprietà è stata concepita. Infine, è necessario fornire un tag di chiusura equivalente che specifica la stessa combinazione nomeTipoElemento.nomeProprietà, opportunamente nidificato e bilanciato con gli altri tag elemento. Ad esempio, di seguito viene riportata la sintassi degli elementi proprietà per la proprietà ContextMenu di Button.

<Button>
  <Button.ContextMenu>
    <ContextMenu>
      <MenuItem Header="1">First item</MenuItem>
      <MenuItem Header="2">Second item</MenuItem>
    </ContextMenu>
  </Button.ContextMenu>
  Right-click me!</Button>

Il valore nell'elemento proprietà può anche essere fornito come testo interno, nei casi in cui il tipo della proprietà specificato è un tipo di valore primitivo, ad esempio String o un'enumerazione in cui viene specificato un nome. Questi due utilizzi non sono comuni, poiché in ciascun caso è supportata anche la sintassi degli attributi. Uno scenario per riempire un elemento proprietà con una stringa riguarda le proprietà diverse dalla proprietà contenuto XAML, che vengono tuttavia utilizzate per la rappresentazione di testo dell'interfaccia utente e quando è necessario visualizzare in tale testo determinati elementi di spazio, quali gli avanzamenti riga. La sintassi degli attributi non può mantenere gli avanzamenti riga, a differenza della sintassi degli elementi proprietà a condizione che il mantenimento degli spazi significativi sia attivo (per informazioni dettagliate, vedere Elaborazione degli spazi vuoti in XAML).

Un elemento proprietà non è rappresentato nell'albero logico. Rappresenta unicamente una sintassi particolare per l'impostazione di una proprietà e non dispone di un'istanza o oggetto che lo supporta.

Sintassi degli elementi proprietà per i tipi di insieme

La specifica XAML richiede che le implementazioni del processore XAML siano in grado di identificare le proprietà in cui il tipo di valore è un insieme. L'implementazione WPF è basata su codice gestito e il relativo processore XAML identifica i tipi di insieme tramite una delle condizioni seguenti:

Se il tipo di una proprietà è un insieme, non è necessario specificare nel markup il tipo di insieme dedotto. Invece, gli elementi destinati a essere gli elementi dell'insieme vengono specificati come uno o più elementi figlio dell'elemento proprietà del tipo di insieme. Ognuno di questi elementi viene valutato in base a un oggetto durante il caricamento e aggiunto all'insieme chiamando il metodo Add dell'insieme implicito. Ad esempio, la proprietà Triggers di Style accetta il tipo di insieme specializzato TriggerCollection. Non è tuttavia necessario creare un'istanza di TriggerCollection nel markup. Specificare invece uno o più elementi Trigger come elementi all'interno dell'elemento proprietà Style.Triggers, dove Trigger (o una classe derivata) è il tipo previsto come tipo di elemento per l'oggetto TriggerCollection fortemente tipizzato e implicito.

<Style x:Key="SpecialButton" TargetType="{x:Type Button}">
  <Style.Triggers>
    <Trigger Property="Button.IsMouseOver" Value="true">
      <Setter Property = "Background" Value="Red"/>
    </Trigger>
    <Trigger Property="Button.IsPressed" Value="true">
      <Setter Property = "Foreground" Value="Green"/>
    </Trigger>
  </Style.Triggers>
</Style>

Una proprietà può essere sia un tipo di insieme sia la proprietà di contenuto XAML per tale tipo e i tipi derivati.

Un elemento insieme implicito crea un membro nell'albero logico, anche se non viene visualizzato nel markup come elemento. In genere, il costruttore del tipo proprietario crea le istanze per l'insieme che rappresenta una delle sue proprietà, tramite cui l'insieme viene aggiunto alla struttura ad albero.

Nota

Le interfacce generiche di elenco dizionario (IList<T> e IDictionary<TKey, TValue>) non sono supportate per il rilevamento degli insiemi da parte del processore XAML WPF. Tuttavia, è possibile utilizzare la classe List<T> come classe di base, poiché implementa direttamente IList oppure Dictionary<TKey, TValue> come classe di base, poiché implementa direttamente IDictionary.

Sintassi del contenuto XAML

La sintassi del contenuto XAML è una sintassi che viene attivata solo su classi che specificano ContentPropertyAttribute come parte della relativa dichiarazione di classe. ContentPropertyAttribute richiede un parametro che specifica la proprietà in base al nome definito come proprietà di contenuto per tale tipo di elemento (incluse le classi derivate). La proprietà designata in questo modo è la proprietà di contenuto XAML di un elemento. In caso di elaborazione da parte di un processore XAML, qualsiasi elemento figlio o testo interno rilevato tra i tag di apertura e di chiusura dell'elemento verrà assegnato come valore di tale proprietà di contenuto XAML. Se si desidera rendere esplicito il markup, è consentito specificare elementi proprietà per la proprietà di contenuto. Questa tecnica ha u n valore occasionale per la chiarezza o lo stile del markup, ma in genere il fine della proprietà di contenuto è semplificare il markup in modo che gli elementi correlati intuitivamente come padre-figlio possano essere nidificati direttamente. I tag degli elementi proprietà per altre proprietà di un elemento non vengono assegnati come "contenuto", ma vengono prima elaborati nel flusso di lavoro del parser e non sono considerati "contenuto."

Come qualsiasi altra proprietà, la proprietà di contenuto XAML di un oggetto sarà di un tipo specifico. Questo tipo può essere il tipo Object. Il tipo di tale proprietà di contenuto agevola la definizione del modello di contenuto di un oggetto. Ad esempio, un tipo di Object è debole in quanto qualsiasi oggetto può diventarne il contenuto, ma anche questa tipizzazione debole richiede che il contenuto sia un singolo oggetto. Il singolo oggetto può essere un oggetto Collection, ma anche in questo caso può esservi un solo oggetto Collection assegnato come contenuto.

Nella documentazione WPF, i modelli di contenuto per determinati tipi sono descritti nelle pagine delle classi per il tipo corrispondente oppure vengono trattati come argomenti separati per famiglie di tipi e collegati a ogni riferimento al tipo rilevante.

Sintassi del contenuto per tipi di insieme

Per accettare più di un singolo elemento oggetto (o testo interno) come contenuto, il tipo della proprietà di contenuto deve essere specificamente un tipo di insieme. Analogamente alla sintassi degli elementi proprietà per i tipi di insieme, è necessario che un processore XAML identifichi quali tipi sono tipi di insieme. Se un elemento presenta una proprietà di contenuto XAML e il tipo della proprietà di contenuto XAML è un insieme, non è necessario specificare il tipo di insieme implicito nel markup come elemento oggetto, né specificare la proprietà di contenuto XAML come elemento proprietà. Pertanto, il modello di contenuto apparente nel markup può presentare più di un elemento figlio assegnato come contenuto. Di seguito viene riportata la sintassi del contenuto per una classe derivata Panel. Tutte le classi derivate da Panel stabiliscono che la proprietà di contenuto XAML sia Children, che richiede un valore di tipo UIElementCollection.

<Page
  xmlns="https://schemas.microsoft.com/winfx/2006/xaml/presentation"
  xmlns:x="https://schemas.microsoft.com/winfx/2006/xaml"
  >
  <StackPanel>
    <Button>Button 1</Button>
    <Button>Button 2</Button>
    <Button>Button 3</Button>
  </StackPanel>
</Page>

Si noti che né l'elemento proprietà per Children, né l'elemento per UIElementCollection è necessario nel markup. Si tratta di una funzionalità di progettazione di XAML, in base alla quale gli elementi contenuti in modo ricorsivo che definiscono un'interfaccia utente vengono rappresentati in modo più intuitivo come una struttura ad albero di elementi nidificati con relazioni padre-figlio immediate, senza tag di elementi proprietà o oggetti Collection estranei. Infatti, per caratteristiche di progettazione, non è possibile specificare UIElementCollection nel markup come elemento oggetto. Poiché il solo utilizzo previsto è come insieme implicito, UIElementCollection non espone un costruttore predefinito pubblico e, di conseguenza, non è possibile crearne un'istanza come elemento oggetto.

Combinazione di elementi proprietà ed elementi oggetto in un oggetto con una proprietà di contenuto

La specifica XAML stabilisce che un processore XAML possa imporre che gli elementi oggetto utilizzati per riempire la proprietà di contenuto XAML all'interno di un elemento oggetto debbano essere contigui, non combinati. Questa restrizione che limita la combinazione di elementi proprietà e contenuto viene imposta dal processore XAML WPF.

È possibile disporre di un elemento oggetto figlio come primo markup all'interno di un elemento oggetto. Successivamente, è possibile introdurre elementi proprietà. In alternativa, è possibile specificare uno o più elementi proprietà, quindi elementi contenuto e, successivamente, altri elementi proprietà. Una volta inserito un elemento proprietà dopo il contenuto, non è possibile inserire altro contenuto, ma solo elementi proprietà.

Questo requisito di ordine tra elementi proprietà e contenuto non si applica al testo interno utilizzato come contenuto. Tuttavia, per uno stile di markup ottimale è bene mantenere contiguo il testo interno, poiché uno spazio vuoto significativo sarà difficile da rilevare visivamente nel markup se sono presenti elementi proprietà inframmezzati da testo interno.

Proprietà associate

Le proprietà associate costituiscono un concetto di programmazione introdotto in XAML in base al quale le proprietà possono essere di proprietà di un tipo ed esserne definite, ma possono essere impostate su qualsiasi elemento. Lo scenario principale a cui sono destinate le proprietà associate è quello di consentire agli elementi figlio nella struttura ad albero di un elemento di fornire informazioni a un elemento padre senza la necessità di un modello a oggetti ampiamente condiviso tra tutti gli elementi. Viceversa, le proprietà associate possono essere utilizzate dagli elementi padre per fornire informazioni agli elementi figlio. Per ulteriori informazioni sullo scopo delle proprietà associate e su come creare proprietà associate personalizzate, vedere Cenni preliminari sulle proprietà associate.

Le proprietà associate utilizzano una sintassi che assomiglia per certi versi alla sintassi degli elementi proprietà, poiché anche in questo caso viene specificata una combinazione nomeTipo.nomeProprietà. Vi sono due differenze importanti:

  • È possibile utilizzare la combinazione nomeTipo.nomeProprietà anche quando si imposta una proprietà associata tramite la sintassi degli attributi. Le proprietà associate costituiscono l'unico caso in cui la qualifica del nome della proprietà è un requisito nella sintassi di un attributi.

  • È anche possibile utilizzare la sintassi degli elementi proprietà per le proprietà associate. Nella sintassi degli elementi proprietà tipica, tuttavia, nomeTipo è l'elemento oggetto che contiene l'elemento proprietà. Se si fa riferimento a una proprietà associata, nomeTipo è la classe che definisce la proprietà associata, non l'elemento oggetto contenitore.

Eventi associati

Gli eventi associati sono un altro concetto di programmazione introdotto in XAML mediante il quale è possibile definire gli eventi mediante un tipo, ma è possibile associare i gestori a qualsiasi oggetto. Il tipo che definisce un evento associato è spesso un tipo statico che definisce un servizio e, in alcuni casi, gli eventi associati sono esposti dall'alias di un evento indirizzato in tipi che espongono il servizio. I gestori per gli eventi associati vengono specificati tramite la sintassi degli attributi. La sintassi degli attributi viene espansa per gli eventi associati per consentire l'utilizzo di nomeTipo.nomeEvento, in cui nomeTipo è la classe che fornisce le funzioni di accesso ai gestori eventi Add e Remove per l'infrastruttura degli eventi associati e nomeEvento è il nome dell'evento.

Spazi dei nomi Xml

In nessuno degli esempi di sintassi precedenti è stato specificato uno spazio dei nomi diverso da quello predefinito. Nelle applicazioni WPF tipiche lo spazio dei nomi predefinito specificato è lo spazio dei nomi WPF. È possibile specificare spazi dei nomi diversi da quello predefinito e continuare a utilizzare sostanzialmente gli stessi tipi di sintassi, ma in tutti i casi in cui viene denominata una classe che non è accessibile all'interno dello spazio dei nomi predefinito, il nome della classe deve essere preceduto dal prefisso dello spazio dei nomi XML utilizzato per il mapping dello spazio dei nomi CLR corrispondente. Ad esempio, <custom:MyElement/> è la sintassi degli elementi oggetto per creare un'istanza della classe MyElement, in cui lo spazio dei nomi CLR che contiene tale classe (ed eventualmente l'assembly esterno che contiene tale spazio dei nomi) è stato precedentemente mappato al prefisso custom.

Per ulteriori informazioni sugli spazi dei nomi XML e su XAML, vedere Spazi dei nomi XAML e mapping dello spazio dei nomi.

Estensioni di markup

In XAML viene definita un'entità di programmazione di estensione di markup che costituisce un'alternativa alla normale gestione di attributi o di elementi oggetto del processore XAML e rinvia l'elaborazione a una classe sottostante. L'implementazione WPF di un processore XAML utilizza la classe astratta MarkupExtension come base per tutte le estensioni di markup supportate da WPF. Il carattere che identifica un'estensione di markup in un processore XAML quando si utilizza la sintassi degli attributi è la parentesi graffa di apertura ({), seguita da qualsiasi carattere a eccezione della parentesi graffa di chiusura (}). La prima stringa che segue la parentesi graffa di apertura deve fare riferimento alla classe che fornisce un particolare comportamento di estensione, in cui nel riferimento è possibile omettere la sottostringa "Estensione" se tale sottostringa fa parte del nome effettivo della classe. Dopodiché, potrebbe essere presente uno spazio singolo e, quindi, ogni carattere successivo viene utilizzato come input dall'implementazione dell'estensione, fino a quando non viene rilevata la parentesi graffa di chiusura. Le estensioni di markup in WPF sono destinate principalmente a fornire un mezzo per fare riferimento ad altri oggetti già esistenti o per rinviare riferimenti a oggetti che verranno valutati in fase di esecuzione, utilizzando la sintassi degli attributi. Ad esempio, una semplice associazione dati viene realizzata specificando l'estensione di markup {Binding} al posto del tipo di valore che verrebbe generalmente accettato da una proprietà specificata. Molte delle estensioni di markup consentono una sintassi degli attributo per le proprietà in cui una sintassi degli attributi non sarebbe altrimenti possibile. Ad esempio, un oggetto Style è un tipo di riferimento relativamente complesso che contiene diverse altre proprietà, ognuna delle quali accetta anche oggetti byref e non primitivi. Gli stili tuttavia vengono creati generalmente come una risorsa e, successivamente, viene fatto loro riferimento tramite una delle due estensioni di markup che richiedono una risorsa. L'estensione rinvia la valutazione del valore di proprietà a una ricerca di risorse e consente di specificare il valore della proprietà Style, che accetta il tipo Style, nella sintassi degli attributi come indicato di seguito:

<Button Style="{StaticResource MyStyle}">My button</Button>

StaticResource identifica la classe StaticResourceExtension che fornisce l'implementazione dell'estensione di markup. La stringa successiva MyStyle viene utilizzata come input per il costruttore StaticResourceExtension non predefinito, in cui il parametro accettato dalla stringa di estensione dichiara l'oggetto ResourceKey richiesto. MyStyle è previsto come valore Attributo x:Key di un oggetto Style definito come risorsa. L'utilizzo di Estensione del markup StaticResource richiede che la risorsa venga utilizzata per fornire il valore di proprietà Style tramite la logica di ricerca delle risorse statica in fase di caricamento.

Per ulteriori informazioni sulle estensioni di markup, vedere Estensioni di markup e XAML. Per un riferimento alle estensioni di markup e ad altre funzionalità di programmazione XAML, vedere Funzionalità del linguaggio dello spazio dei nomi XAML (x:) e Estensioni XAML degli spazi dei nomi WPF.

Utilizzi facoltativi e non consigliati di XAML

Utilizzi facoltativi degli elementi proprietà

Gli utilizzi facoltativi degli elementi proprietà includono l'indicazione specifica di proprietà di contenuto degli elementi considerate implicite dal processore XAML. Ad esempio, quando si dichiara il contenuto di Menu, è possibile scegliere di dichiarare in modo esplicito l'insieme Items di Menu come tag dell'elemento proprietà <Menu.Items> e posizionare ciascun oggetto MenuItem all'interno di <Menu.Items>, anziché utilizzare il comportamento implicito del processore XAML che stabilisce che tutti gli elementi figlio di un oggetto Menu debbano essere MenuItem e vengano posizionati nell'insieme Items. In alcuni casi gli utilizzi facoltativi possono consentire di chiarire visivamente la struttura dell'oggetto così come è rappresentata nel markup. In altri casi, un utilizzo esplicito di un elemento proprietà può evitare un markup tecnicamente funzionale ma visivamente confuso, ad esempio nel caso di estensioni di markup nidificate in un valore di attributo.

Attributi qualificati nomeTipo.nomeMembro completi

Il formato nomeTipo.nomeMembro per un attributo può essere effettivamente utilizzato in modo più ampio rispetto agli eventi indirizzati, ma in altre applicazioni tale formato è superfluo ed è opportuno evitarlo, anche solo per motivi di stile del markup e di leggibilità. Nell'esempio riportato di seguito, ognuno dei tre riferimenti all'attributo Background è completamente equivalente:

<Button Background="Blue">Background</Button>
<Button Button.Background="Blue">Button.Background</Button>
<Button Control.Background="Blue">Control.Background</Button>

È possibile utilizzare Button.Background poiché la ricerca qualificata per tale proprietà in Button è riuscita (Background è stato ereditato da Control) e Button è la classe dell'elemento oggetto o una classe di base. È possibile utilizzare Control.Background poiché la classe Control definisce effettivamente Background e Control è una classe di base Button.

Tuttavia, non è possibile utilizzare l'esempio di formato nomeTipo.nomeMembro riportato di seguito in cui sono visualizzati i commenti:

<!--<Button Label.Background="Blue">Does not work</Button> -->

Label è un'altra classe derivata di Control e se fosse stato specificato Label.Background all'interno di un elemento oggetto Label, questo utilizzo avrebbe avuto esito positivo. Tuttavia, poiché Label non è la classe o la classe di base di Button, il comportamento del processore XAML specificato consiste nell'elaborazione di Label.Background come proprietà associata. Label.Background non è una proprietà associata e questo utilizzo ha esito negativo.

Elementi proprietà nomeTipoBase.nomeMembro

Analogamente al funzionamento del formato nomeTipo.nomeMembro per la sintassi degli attributi, per la sintassi degli elementi proprietà è possibile utilizzare una sintassi nomeTipoBase.nomeMembro. Ad esempio, è possibile utilizzare la sintassi riportata di seguito:

<Button>Control.Background PE
  <Control.Background>
    <LinearGradientBrush StartPoint="0,0" EndPoint="1,1">
      <GradientStop Color="Yellow" Offset="0.0" />
      <GradientStop Color="LimeGreen" Offset="1.0" />
    </LinearGradientBrush>
    </Control.Background>
</Button>

In questo caso, l'elemento proprietà viene fornito come Control.Background anche se era contenuto in Button.

Analogamente al formato nomeTipo.nomeMembro per gli attributi, tuttavia, nomeTipoBase.nomeMembro non rappresenta uno stile di markup ottimale ed è opportuno evitarlo per tale motivo.

Vedere anche

Concetti

Cenni preliminari su XAML

Cenni preliminari sulle proprietà di dipendenza

TypeConverter e XAML

XAML e classi personalizzate

Altre risorse

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

Estensioni XAML degli spazi dei nomi WPF