Xamarin.Forms dizionari risorse
Un ResourceDictionary
è un repository per le risorse usate da un'applicazione Xamarin.Forms . Le risorse tipiche archiviate in un ResourceDictionary
oggetto includono stili, modelli di controllo, modelli di dati, colori e convertitori.
In XAML è possibile fare riferimento alle risorse archiviate in un ResourceDictionary
oggetto e applicarle agli elementi usando l'estensione StaticResource
di markup o DynamicResource
. In C# le risorse possono anche essere definite in un ResourceDictionary
oggetto e quindi a cui si fa riferimento e applicate agli elementi usando un indicizzatore basato su stringa. Tuttavia, l'uso di in ResourceDictionary
C# può risultare poco vantaggioso, poiché gli oggetti condivisi possono essere archiviati come campi o proprietà ed è possibile accedervi direttamente senza dover prima recuperarli da un dizionario.
Creare risorse in XAML
Ogni VisualElement
oggetto derivato ha una Resources
proprietà , ovvero un oggetto ResourceDictionary
che può contenere risorse. Analogamente, un Application
oggetto derivato ha una Resources
proprietà , ovvero un ResourceDictionary
oggetto che può contenere risorse.
Un'applicazione Xamarin.Forms contiene solo una classe che deriva da Application
, ma spesso usa molte classi che derivano da VisualElement
, incluse pagine, layout e controlli. Uno di questi oggetti può avere la relativa Resources
proprietà impostata su un ResourceDictionary
oggetto contenente le risorse. Scelta della posizione in cui inserire un impatto particolare ResourceDictionary
in cui è possibile usare le risorse:
- Le risorse in un oggetto
ResourceDictionary
collegato a una vista, ad esempioButton
oLabel
, possono essere applicate solo a tale oggetto specifico. - Le risorse in un
ResourceDictionary
layout collegato a un layout,StackLayout
ad esempio oGrid
, possono essere applicate al layout e a tutti gli elementi figlio di tale layout. - Le risorse in un
ResourceDictionary
oggetto definito a livello di pagina possono essere applicate alla pagina e a tutti i relativi elementi figlio. - Le risorse in un
ResourceDictionary
definito a livello di applicazione possono essere applicate in tutta l'applicazione.
Ad eccezione degli stili impliciti, ogni risorsa nel dizionario risorse deve avere una chiave stringa univoca definita con l'attributo x:Key
.
Il codice XAML seguente mostra le risorse definite in un livello ResourceDictionary
di applicazione nel file App.xaml :
<Application xmlns="http://xamarin.com/schemas/2014/forms"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
x:Class="ResourceDictionaryDemo.App">
<Application.Resources>
<Thickness x:Key="PageMargin">20</Thickness>
<!-- Colors -->
<Color x:Key="AppBackgroundColor">AliceBlue</Color>
<Color x:Key="NavigationBarColor">#1976D2</Color>
<Color x:Key="NavigationBarTextColor">White</Color>
<Color x:Key="NormalTextColor">Black</Color>
<!-- Implicit styles -->
<Style TargetType="{x:Type NavigationPage}">
<Setter Property="BarBackgroundColor"
Value="{StaticResource NavigationBarColor}" />
<Setter Property="BarTextColor"
Value="{StaticResource NavigationBarTextColor}" />
</Style>
<Style TargetType="{x:Type ContentPage}"
ApplyToDerivedTypes="True">
<Setter Property="BackgroundColor"
Value="{StaticResource AppBackgroundColor}" />
</Style>
</Application.Resources>
</Application>
In questo esempio il dizionario risorse definisce una Thickness
risorsa, più Color
risorse e due risorse implicite Style
. Per altre informazioni sulla App
classe, vedere Xamarin.Forms Classe app.
Nota
È anche possibile inserire tutte le risorse tra tag espliciti ResourceDictionary
. Tuttavia, poiché Xamarin.Forms 3.0 i ResourceDictionary
tag non sono necessari. L'oggetto ResourceDictionary
viene invece creato automaticamente ed è possibile inserire le risorse direttamente tra i tag dell'elemento Resources
proprietà.
Usare le risorse in XAML
Ogni risorsa ha una chiave specificata usando l'attributo x:Key
, che diventa la chiave del dizionario in ResourceDictionary
. La chiave viene usata per fare riferimento a una risorsa da con l'estensione ResourceDictionary
StaticResource
di markup o DynamicResource
.
L'estensione StaticResource
di markup è simile all'estensione DynamicResource
di markup in quanto entrambi usano una chiave del dizionario per fare riferimento a un valore da un dizionario risorse. Tuttavia, mentre l'estensione StaticResource
di markup esegue una ricerca in un singolo dizionario, l'estensione DynamicResource
di markup mantiene un collegamento alla chiave del dizionario. Pertanto, se la voce del dizionario associata alla chiave viene sostituita, la modifica viene applicata all'elemento visivo. Ciò consente di apportare modifiche alle risorse di runtime in un'applicazione. Per altre informazioni sulle estensioni di markup, vedi Estensioni di markup XAML.
L'esempio XAML seguente illustra come usare le risorse e definisce anche risorse aggiuntive in un StackLayout
oggetto :
<ContentPage xmlns="http://xamarin.com/schemas/2014/forms"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
x:Class="ResourceDictionaryDemo.HomePage"
Title="Home Page">
<StackLayout Margin="{StaticResource PageMargin}">
<StackLayout.Resources>
<!-- Implicit style -->
<Style TargetType="Button">
<Setter Property="FontSize" Value="Medium" />
<Setter Property="BackgroundColor" Value="#1976D2" />
<Setter Property="TextColor" Value="White" />
<Setter Property="CornerRadius" Value="5" />
</Style>
</StackLayout.Resources>
<Label Text="This app demonstrates consuming resources that have been defined in resource dictionaries." />
<Button Text="Navigate"
Clicked="OnNavigateButtonClicked" />
</StackLayout>
</ContentPage>
In questo esempio, l'oggetto ContentPage
utilizza lo stile implicito definito nel dizionario risorse a livello di applicazione. L'oggetto StackLayout
utilizza la PageMargin
risorsa definita nel dizionario risorse a livello di applicazione, mentre l'oggetto Button
utilizza lo stile implicito definito nel StackLayout
dizionario risorse. Il risultato è l'aspetto illustrato negli screenshot seguenti:
Importante
Le risorse specifiche di una singola pagina non devono essere incluse in un dizionario risorse a livello di applicazione, in quanto tali risorse verranno quindi analizzate all'avvio dell'applicazione anziché quando richiesto da una pagina. Per altre informazioni, vedere Ridurre le dimensioni del dizionario risorse dell'applicazione.
Comportamento di ricerca delle risorse
Il processo di ricerca seguente si verifica quando viene fatto riferimento a una risorsa con l'estensione StaticResource
di markup o DynamicResource
:
- La chiave richiesta viene verificata nel dizionario risorse, se esistente, per l'elemento che imposta la proprietà. Se viene trovata la chiave richiesta, viene restituito il relativo valore e il processo di ricerca termina.
- Se non viene trovata una corrispondenza, il processo di ricerca cerca la struttura ad albero visuale verso l'alto, controllando il dizionario risorse di ogni elemento padre. Se viene trovata la chiave richiesta, viene restituito il relativo valore e il processo di ricerca termina. In caso contrario, il processo continua verso l'alto fino a quando non viene raggiunto l'elemento radice.
- Se non viene trovata una corrispondenza nell'elemento radice, viene esaminato il dizionario risorse a livello di applicazione.
- Se non viene ancora trovata una corrispondenza, viene generata un'eccezione
XamlParseException
.
Pertanto, quando il parser XAML rileva un'estensione StaticResource
di markup o DynamicResource
, cerca una chiave corrispondente passando attraverso la struttura ad albero visuale, usando la prima corrispondenza trovata. Se la ricerca termina nella pagina e la chiave non è ancora stata trovata, il parser XAML cerca nell'oggetto ResourceDictionary
App
associato. Se la chiave non viene ancora trovata, viene generata un'eccezione.
Eseguire l'override delle risorse
Quando le risorse condividono le chiavi, le risorse definite più in basso nella struttura ad albero visuale avranno la precedenza su quelle definite più in alto. Ad esempio, l'impostazione di una AppBackgroundColor
risorsa su AliceBlue
a livello di applicazione verrà sostituita da una risorsa a livello AppBackgroundColor
di pagina impostata su Teal
. Analogamente, una risorsa a livello AppBackgroundColor
di pagina verrà sostituita da una risorsa a livello AppBackgroundColor
di controllo.
Dizionari risorse autonomi
Una classe derivata da ResourceDictionary
può anche trovarsi in un file XAML autonomo. Il file XAML può quindi essere condiviso tra le applicazioni.
Per creare un file di questo tipo, aggiungere un nuovo elemento Visualizzazione contenuto o Pagina contenuto al progetto (ma non una visualizzazione contenuto o una pagina contenuto con solo un file C#). Eliminare il file code-behind e nel file XAML modificare il nome della classe di base da ContentView
o ContentPage
in ResourceDictionary
. Rimuovere inoltre l'attributo x:Class
dal tag radice del file.
L'esempio XAML seguente mostra un ResourceDictionary
oggetto denominato MyResourceDictionary.xaml:
<ResourceDictionary xmlns="http://xamarin.com/schemas/2014/forms"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml">
<DataTemplate x:Key="PersonDataTemplate">
<ViewCell>
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="0.5*" />
<ColumnDefinition Width="0.2*" />
<ColumnDefinition Width="0.3*" />
</Grid.ColumnDefinitions>
<Label Text="{Binding Name}"
TextColor="{StaticResource NormalTextColor}"
FontAttributes="Bold" />
<Label Grid.Column="1"
Text="{Binding Age}"
TextColor="{StaticResource NormalTextColor}" />
<Label Grid.Column="2"
Text="{Binding Location}"
TextColor="{StaticResource NormalTextColor}"
HorizontalTextAlignment="End" />
</Grid>
</ViewCell>
</DataTemplate>
</ResourceDictionary>
In questo esempio l'oggetto ResourceDictionary
contiene una singola risorsa, ovvero un oggetto di tipo DataTemplate
. MyResourceDictionary.xaml può essere utilizzato unendolo in un altro dizionario risorse.
Per impostazione predefinita, il linker rimuoverà i file XAML autonomi dalle build di rilascio quando il comportamento del linker è impostato per collegare tutti gli assembly. Per garantire che i file XAML autonomi rimangano in una build di versione:
Aggiungere un attributo personalizzato
Preserve
all'assembly contenente i file XAML autonomi. Per altre informazioni, vedere Conservazione del codice.Impostare l'attributo
Preserve
a livello di assembly:[assembly:Preserve(AllMembers = true)]
Per altre informazioni sul collegamento, vedere Collegamento di app Xamarin.iOS e collegamento in Android.
Dizionari di risorse unite
I dizionari risorse uniti combinano uno o più ResourceDictionary
oggetti in un altro ResourceDictionary
oggetto .
Unire dizionari risorse locali
Un file locale ResourceDictionary
può essere unito a un altro ResourceDictionary
creando un ResourceDictionary
oggetto la cui Source
proprietà è impostata sul nome file del file XAML con le risorse:
<ContentPage ...>
<ContentPage.Resources>
<!-- Add more resources here -->
<ResourceDictionary Source="MyResourceDictionary.xaml" />
<!-- Add more resources here -->
</ContentPage.Resources>
...
</ContentPage>
Questa sintassi non crea un'istanza della MyResourceDictionary
classe . Fa invece riferimento al file XAML. Per questo motivo, quando si imposta la Source
proprietà , non è necessario un file code-behind e l'attributo x:Class
può essere rimosso dal tag radice del file MyResourceDictionary.xaml .
Importante
La Source
proprietà può essere impostata solo da XAML.
Unire dizionari risorse da altri assembly
Un ResourceDictionary
oggetto può anche essere unito in un altro ResourceDictionary
aggiungendolo nella MergedDictionaries
proprietà di ResourceDictionary
. Questa tecnica consente di unire i dizionari delle risorse, indipendentemente dall'assembly in cui risiedono. L'unione di dizionari risorse da assembly esterni richiede che sia ResourceDictionary
impostata un'azione di compilazione su EmbeddedResource, che disponga di un file code-behind e di definire l'attributo x:Class
nel tag radice del file.
Avviso
Anche la classe ResourceDictionary
definisce una proprietà MergedWith
. Tuttavia, questa proprietà è stata deprecata e non deve più essere utilizzata.
L'esempio di codice seguente mostra due dizionari di risorse aggiunti alla MergedDictionaries
raccolta di un livello ResourceDictionary
di pagina:
<ContentPage ...
xmlns:local="clr-namespace:ResourceDictionaryDemo"
xmlns:theme="clr-namespace:MyThemes;assembly=MyThemes">
<ContentPage.Resources>
<ResourceDictionary>
<!-- Add more resources here -->
<ResourceDictionary.MergedDictionaries>
<!-- Add more resource dictionaries here -->
<local:MyResourceDictionary />
<theme:LightTheme />
<!-- Add more resource dictionaries here -->
</ResourceDictionary.MergedDictionaries>
<!-- Add more resources here -->
</ResourceDictionary>
</ContentPage.Resources>
...
</ContentPage>
In questo esempio, un dizionario risorse dello stesso assembly e un dizionario risorse di un assembly esterno vengono uniti nel dizionario risorse a livello di pagina. Inoltre, è anche possibile aggiungere altri ResourceDictionary
oggetti all'interno dei MergedDictionaries
tag property-element e altre risorse all'esterno di tali tag.
Importante
In un ResourceDictionary
oggetto può essere presente un MergedDictionaries
solo tag di elemento proprietà, ma è possibile inserire tutti gli ResourceDictionary
oggetti in tale elemento come richiesto.
Quando le risorse unite ResourceDictionary
condividono valori di attributo identici x:Key
, Xamarin.Forms usa la precedenza della risorsa seguente:
- Risorse locali del dizionario risorse.
- Le risorse contenute nei dizionari risorse unite tramite la
MergedDictionaries
raccolta, nell'ordine inverso in cui sono elencate nellaMergedDictionaries
proprietà .
Nota
La ricerca di dizionari risorse può essere un'attività a elevato utilizzo di calcolo se un'applicazione contiene più dizionari di risorse di grandi dimensioni. Pertanto, per evitare ricerche non necessarie, è necessario assicurarsi che ogni pagina in un'applicazione usi solo dizionari risorse appropriati per la pagina.
Collegamenti correlati
- Estensioni di markup XAML
- Xamarin.Forms Stili
- Collegamento di app Xamarin.iOS
- Collegamento in Android
- ResourceDictionary API
Video correlato
Altri video di Xamarin sono disponibili su Channel 9 e YouTube.