Estensione di markup {ThemeResource}

Fornisce un valore per qualsiasi attributo XAML valutando un riferimento a una risorsa, con logica di sistema aggiuntiva che recupera risorse diverse a seconda del tema attualmente attivo. Analogamente all'estensione di markup {StaticResource}, le risorse vengono definite in resourceDictionary e un utilizzo ThemeResource fa riferimento alla chiave di tale risorsa in ResourceDictionary.

Utilizzo attributo XAML

<object property="{ThemeResource key}" .../>

Valori XAML

Termine Descrizione
chiave Chiave per la risorsa richiesta. Questa chiave viene inizialmente assegnata da ResourceDictionary. Una chiave di risorsa può essere qualsiasi stringa definita nella grammatica XamlName.

Osservazioni:

ThemeResource è una tecnica per ottenere valori per un attributo XAML definito altrove in un dizionario risorse XAML. L'estensione di markup ha lo stesso scopo di base dell'estensione di markup {StaticResource}. La differenza di comportamento rispetto all'estensione di markup {StaticResource} consiste nel fatto che un riferimento ThemeResource può usare in modo dinamico dizionari diversi come percorso di ricerca principale, a seconda del tema attualmente usato dal sistema.

All'avvio dell'app, tutti i riferimenti alle risorse effettuati da un riferimento ThemeResource vengono valutati in base al tema in uso all'avvio. Tuttavia, se successivamente l'utente modifica il tema attivo in fase di esecuzione, il sistema valuterà nuovamente ogni riferimento ThemeResource , recupererà una risorsa specifica del tema che potrebbe essere diversa e visualizzerà nuovamente l'app con nuovi valori di risorsa in tutte le posizioni appropriate nella struttura ad albero visuale. Un oggetto StaticResource viene determinato in fase di caricamento XAML/avvio dell'app e non verrà rivalutato in fase di esecuzione. Esistono altre tecniche, ad esempio gli stati di visualizzazione, che ricaricano XAML in modo dinamico, ma queste tecniche operano a un livello superiore che la valutazione delle risorse di base abilitata da Estensione di markup {StaticResource}).

ThemeResource accetta un argomento, che specifica la chiave per la risorsa richiesta. Una chiave di risorsa è sempre una stringa in XAML di Windows Runtime. Per altre info su come viene inizialmente specificata la chiave di risorsa, vedi attributo x:Key.

Per altre info su come definire le risorse e usare correttamente un ResourceDictionary, incluso il codice di esempio, vedi Riferimenti alle risorse ResourceDictionary e XAML.

Importante Come per StaticResource, un oggetto ThemeResource non deve tentare di eseguire un riferimento in avanti a una risorsa definita in modo lessicale all'interno del file XAML. Il tentativo di eseguire questa operazione non è supportato. Anche se il riferimento in avanti non ha esito negativo, il tentativo di crearne uno comporta una riduzione delle prestazioni. Per ottenere risultati ottimali, modificare la composizione dei dizionari risorse in modo che i riferimenti in avanti vengano evitati.

Il tentativo di specificare themeResource su una chiave che non può risolvere genera un'eccezione di analisi XAML in fase di esecuzione. Gli strumenti di progettazione possono anche offrire avvisi o errori.

Nell'implementazione del processore XAML di Windows Runtime non esiste alcuna rappresentazione della classe di supporto per ThemeResource. L'equivalente più vicino nel codice consiste nell'usare l'API di raccolta di un oggetto ResourceDictionary, ad esempio chiamando Contains o *TryGetValue.

ThemeResource è un'estensione di markup. Le estensioni di markup in genere vengono implementate quando per i valori dell'attributo devono essere utilizzati caratteri escape in modo che non vengano considerati come valori letterali o nomi di gestori e il requisito è più globale del semplice utilizzo di convertitori dei tipi su alcuni tipi o proprietà. Tutte le estensioni di markup in XAML usano i caratteri "{" e "}" nella sintassi degli attributi, ovvero la convenzione in base alla quale un processore XAML riconosce che un'estensione di markup deve elaborare l'attributo.

Quando e come usare {ThemeResource} anziché {StaticResource}

Le regole in base alle quali un Oggetto ThemeResource viene risolto in un elemento in un dizionario risorse sono in genere uguali a StaticResource. Una ricerca ThemeResource può estendersi nei file ResourceDictionary a cui viene fatto riferimento in un insieme ThemeDictionaries, ma è possibile eseguire questa operazione anche in staticResource. La differenza è che themeResource può rivalutare in fase di esecuzione e un oggetto StaticResource non può.

Il set di chiavi in ogni dizionario dei temi deve fornire lo stesso set di risorse con chiave indipendentemente dal tema attivo. Se esiste una determinata risorsa con chiave nel dizionario dei temi HighContrast , un'altra risorsa con tale nome dovrebbe esistere anche in Light e Default. In caso contrario, la ricerca delle risorse potrebbe non riuscire quando l'utente cambia i temi e l'app non avrà un aspetto corretto. È possibile che un dizionario dei temi possa contenere risorse con chiave a cui viene fatto riferimento solo dall'interno dello stesso ambito per fornire valori secondari; questi non devono essere equivalenti in tutti i temi.

In generale, è consigliabile inserire le risorse nei dizionari dei temi e fare riferimenti a tali risorse usando ThemeResource solo quando tali valori possono cambiare tra temi o sono supportati dai valori che cambiano. Questa opzione è appropriata per questi tipi di risorse:

  • Pennelli, in particolare colori per SolidColorBrush. Questi costituiscono circa l'80 % degli utilizzi ThemeResource nei modelli di controllo XAML predefiniti (generic.xaml).
  • Valori pixel per bordi, offset, margine e spaziatura interna e così via.
  • Proprietà del tipo di carattere, ad esempio FontFamily o FontSize.
  • Modelli completi per un numero limitato di controlli che in genere sono in stile di sistema e usati per la presentazione dinamica, ad esempio GridViewItem e ListViewItem.
  • Stili di visualizzazione del testo (in genere per modificare il colore del carattere, lo sfondo e possibilmente le dimensioni).

Windows Runtime fornisce un set di risorse a cui si intende fare riferimento in modo specifico da ThemeResource. Sono tutti elencati come parte del file XAML themeresources.xaml, disponibile nella cartella include/winrt/xaml/design come parte di Windows Software Development Kit (SDK). Per la documentazione sui pennelli del tema e sugli stili aggiuntivi definiti in themeresources.xaml, vedi Risorse del tema XAML. I pennelli sono documentati in una tabella che indica il valore di colore di ogni pennello per ognuno dei tre temi attivi possibili.

Le definizioni XAML degli stati di visualizzazione in un modello di controllo devono usare riferimenti ThemeResource ogni volta che è presente una risorsa sottostante che potrebbe cambiare a causa di una modifica del tema. Una modifica del tema di sistema in genere non causa anche una modifica dello stato di visualizzazione. Le risorse devono usare riferimenti ThemeResource in questo caso in modo che i valori possano essere rivalutati per lo stato di visualizzazione ancora attivo. Ad esempio, se si dispone di uno stato di visualizzazione che modifica il colore di un pennello di una particolare parte dell'interfaccia utente e di una delle relative proprietà e che il colore del pennello è diverso per tema, è consigliabile usare un riferimento ThemeResource per fornire il valore della proprietà nel modello predefinito e anche qualsiasi modifica dello stato visivo al modello predefinito.

Gli utilizzi di ThemeResource potrebbero essere visualizzati in una serie di valori dipendenti. Ad esempio, un valore Color usato da un oggetto SolidColorBrush che è anche una risorsa con chiave potrebbe usare un riferimento ThemeResource. Tuttavia, tutte le proprietà dell'interfaccia utente che usano la risorsa SolidColorBrush con chiave userebbero anche un riferimento ThemeResource, in modo che sia specificamente ogni proprietà di tipo Brush che abilita una modifica di valore dinamico quando il tema cambia.

La{ThemeResource} valutazione delle risorse in fase di esecuzione sul cambio di tema è supportata in XAML di Windows 8.1, ma non è supportata in XAML per le app destinate a Windows 8.

Risorse di sistema

Alcune risorse del tema fanno riferimento ai valori delle risorse di sistema come sottovalore sottostante. Una risorsa di sistema è un valore di risorsa speciale che non viene trovato in alcun dizionario risorse XAML. Questi valori si basano sul comportamento del supporto XAML di Windows Runtime per inoltrare i valori dal sistema stesso e rappresentarli in un formato a cui può fare riferimento una risorsa XAML. Ad esempio, esiste una risorsa di sistema denominata "SystemColorButtonFaceColor" che rappresenta un colore RGB. Questo colore deriva dagli aspetti dei colori di sistema e dei temi che non sono solo specifici per le app di Windows Runtime e Windows Runtime.

Le risorse di sistema sono spesso i valori sottostanti per un tema a contrasto elevato. L'utente ha il controllo delle scelte di colore per il tema a contrasto elevato e l'utente effettua queste scelte usando funzionalità di sistema che non sono specifiche anche per le app di Windows Runtime. Facendo riferimento alle risorse di sistema come riferimenti ThemeResource , il comportamento predefinito dei temi a contrasto elevato per le app di Windows Runtime può usare questi valori specifici del tema controllati dall'utente ed esposti dal sistema. Inoltre, i riferimenti sono ora contrassegnati per la rivalutazione se il sistema rileva una modifica del tema in fase di esecuzione.

Esempio di utilizzo di {ThemeResource}

Ecco un esempio di XAML tratto dai file generic.xaml e themeresources.xaml predefiniti per illustrare come usare ThemeResource. Esamineremo solo un modello (il pulsante predefinito) e il modo in cui due proprietà vengono dichiarate (Background e Foreground) per rispondere alle modifiche del tema.

    <!-- Default style for Windows.UI.Xaml.Controls.Button -->
    <Style TargetType="Button">
        <Setter Property="Background" Value="{ThemeResource ButtonBackgroundThemeBrush}" />
        <Setter Property="Foreground" Value="{ThemeResource ButtonForegroundThemeBrush}"/>
...

In questo caso, le proprietà accettano un valore Brush e il riferimento alle risorse SolidColorBrush denominate ButtonBackgroundThemeBrush e ButtonForegroundThemeBrush vengono create usando ThemeResource.

Queste stesse proprietà vengono regolate anche da alcuni degli stati di visualizzazione per un controllo Button. In particolare, il colore di sfondo cambia quando si fa clic su un pulsante. Anche in questo caso, le animazioni Background e Foreground nello storyboard dello stato visivo usano gli oggetti DiscreteObjectKeyFrame e i riferimenti ai pennelli con ThemeResource come valore del fotogramma chiave.

<VisualState x:Name="Pressed">
  <Storyboard>
    <ObjectAnimationUsingKeyFrames Storyboard.TargetName="Border"
        Storyboard.TargetProperty="Background">
      <DiscreteObjectKeyFrame KeyTime="0" Value="{ThemeResource ButtonPressedBackgroundThemeBrush}" />
    </ObjectAnimationUsingKeyFrames>
    <ObjectAnimationUsingKeyFrames Storyboard.TargetName="ContentPresenter"
         Storyboard.TargetProperty="Foreground">
       <DiscreteObjectKeyFrame KeyTime="0" Value="{ThemeResource ButtonPressedForegroundThemeBrush}" />
    </ObjectAnimationUsingKeyFrames>
  </Storyboard>
</VisualState>

Ognuno di questi pennelli è definito in precedenza in generic.xaml: devono essere definiti prima di tutti i modelli che li usano per evitare riferimenti in avanti XAML. Ecco queste definizioni per il dizionario dei temi "Predefinito".

    <ResourceDictionary.ThemeDictionaries>
        <ResourceDictionary x:Key="Default">
...
            <SolidColorBrush x:Key="ButtonBackgroundThemeBrush" Color="Transparent" />
            <SolidColorBrush x:Key="ButtonForegroundThemeBrush" Color="#FFFFFFFF" />
...
            <SolidColorBrush x:Key="ButtonPressedBackgroundThemeBrush" Color="#FFFFFFFF" />
            <SolidColorBrush x:Key="ButtonPressedForegroundThemeBrush" Color="#FF000000" />
...

Ognuno degli altri dizionari dei temi ha quindi definito questi pennelli, ad esempio:

        <ResourceDictionary x:Key="HighContrast">
            <!-- High Contrast theme resources -->
...
            <SolidColorBrush x:Key="ButtonBackgroundThemeBrush" Color="{ThemeResource SystemColorButtonFaceColor}" />
            <SolidColorBrush x:Key="ButtonForegroundThemeBrush" Color="{ThemeResource SystemColorButtonTextColor}" />

...
            <SolidColorBrush x:Key="ButtonPressedBackgroundThemeBrush" Color="{ThemeResource SystemColorButtonTextColor}" />
            <SolidColorBrush x:Key="ButtonPressedForegroundThemeBrush" Color="{ThemeResource SystemColorButtonFaceColor}" />

Qui il valore Color è un altro riferimento ThemeResource a una risorsa di sistema. Se si fa riferimento a una risorsa di sistema e si vuole che venga modificato in risposta a una modifica del tema, è consigliabile usare ThemeResource per apportare il riferimento.

Comportamento di Windows 8

Windows 8 non supporta l'estensione di markup ThemeResource , ma è disponibile a partire da Windows 8.1. Inoltre, Windows 8 non supportava il cambio dinamico delle risorse correlate al tema per un'app di Windows Runtime. L'app doveva essere riavviata per raccogliere la modifica del tema per i modelli e gli stili XAML. Questa non è un'esperienza utente ottimale, quindi le app sono fortemente incoraggiate a ricompilare e assegnare Windows 8.1 in modo che possano usare gli stili con l'uso di ThemeResource e cambiare dinamicamente i temi quando l'utente lo fa. Le app compilate per Windows 8 ma in esecuzione in Windows 8.1 continuano a usare il comportamento di Windows 8.

Supporto degli strumenti in fase di progettazione per l'estensione di markup {ThemeResource}

Microsoft Visual Studio 2013 può includere possibili valori di chiave negli elenchi a discesa di Microsoft IntelliSense quando si usa l'estensione di markup {ThemeResource} in una pagina XAML. Ad esempio, non appena si digita "{ThemeResource", vengono visualizzate le chiavi di risorsa dalle risorse del tema XAML.

Dopo l'esistenza di una chiave di risorsa come parte di qualsiasi utilizzo di {ThemeResource} , la funzionalità Vai a definizione (F12) può risolvere tale risorsa e visualizzare il file generic.xaml per la fase di progettazione, in cui è definita la risorsa del tema. Poiché le risorse del tema sono definite più volte (per tema) Vai a definizione consente di passare alla prima definizione trovata nel file, ovvero la definizione per Default. Se si desidera che le altre definizioni sia possibile cercare il nome della chiave all'interno del file e trovare le definizioni degli altri temi.