Caricare immagini e asset personalizzati per scala, tema, contrasto elevato e altro

La tua app può caricare file di risorse immagine (o altri file di risorse) contenenti immagini personalizzate per il fattore di scala dello schermo, il tema, il contrasto elevato e altri contesti di runtime. È possibile fare riferimento a queste immagini dal codice imperativo o dal markup XAML, ad esempio come proprietà Source di un oggetto Image. Possono anche essere visualizzati nel file di origine del manifesto del pacchetto dell'app (il Package.appxmanifest file), ad esempio come valore per l'icona dell'app nella scheda Asset visivi della finestra di progettazione manifesto di Visual Studio, oppure nei riquadri e negli avvisi popup. Usando qualificatori nei nomi dei file delle immagini e, facoltativamente, caricandoli dinamicamente con l'aiuto di ResourceContext, è possibile caricare il file di immagine più appropriato che corrisponda meglio alle impostazioni di runtime dell'utente per la scala di visualizzazione, il tema, il contrasto elevato, la lingua e altri contesti.

Una risorsa immagine è contenuta in un file di risorse immagine. È anche possibile considerare l'immagine come un asset e il file che lo contiene come file di asset; ed è possibile trovare questi tipi di file di risorse nella cartella \Assets del progetto. Per informazioni su come usare qualificatori nei nomi dei file di risorse immagine, vedere Adattare le risorse per lingua, scalabilità e altri qualificatori.

Alcuni qualificatori comuni per le immagini sono scale, theme, contrast e targetsize.

Qualificare una risorsa immagine per la scalabilità, il tema e il contrasto

Il valore predefinito per il scale qualificatore è scale-100. Quindi, queste due varianti sono equivalenti (entrambe forniscono un'immagine su scala 100 o fattore di scala 1).

\Assets\Images\logo.png
\Assets\Images\logo.scale-100.png

È possibile usare i qualificatori nei nomi delle cartelle anziché nei nomi di file. Questa sarebbe una strategia migliore se si dispone di diversi file di asset per qualificatore. Ai fini dell'illustrazione, queste due varianti sono equivalenti alle due precedenti.

\Assets\Images\logo.png
\Assets\Images\scale-100\logo.png

Di seguito è riportato un esempio di come è possibile fornire varianti di una risorsa immagine, denominata /Assets/Images/logo.png, per impostazioni diverse della scala di visualizzazione, del tema e del contrasto elevato. In questo esempio viene utilizzata la denominazione delle cartelle.

\Assets\Images\contrast-standard\theme-dark
	\scale-100\logo.png
	\scale-200\logo.png
\Assets\Images\contrast-standard\theme-light
	\scale-100\logo.png
	\scale-200\logo.png
\Assets\Images\contrast-high
	\scale-100\logo.png
	\scale-200\logo.png

Fare riferimento a un'immagine o a un altro asset dal markup e dal codice XAML

Il nome, o l'identificatore, di una risorsa immagine è il percorso e il nome del file con tutti i qualificatori rimossi. Se si denominano cartelle e/o file come in uno degli esempi nella sezione precedente, si dispone di una singola risorsa immagine e il relativo nome (come percorso assoluto) è /Assets/Images/logo.png. Ecco come usare il nome nel markup XAML.

<Image x:Name="myXAMLImageElement" Source="ms-appx:///Assets/Images/logo.png"/>

Si noti che si usa lo ms-appx schema URI perché si fa riferimento a un file proveniente dal pacchetto dell'app. Vedere Schemi URI. Ecco come fare riferimento alla stessa risorsa immagine nel codice imperativo.

this.myXAMLImageElement.Source = new BitmapImage(new Uri("ms-appx:///Assets/Images/logo.png"));

Puoi usare ms-appx per caricare qualsiasi file arbitrario dal pacchetto dell'app.

var uri = new System.Uri("ms-appx:///Assets/anyAsset.ext");
var storagefile = await Windows.Storage.StorageFile.GetFileFromApplicationUriAsync(uri);

Lo ms-appx-web schema accede agli stessi file di ms-appx, ma nel raggruppamento Web.

<WebView x:Name="myXAMLWebViewElement" Source="ms-appx-web:///Pages/default.html"/>
this.myXAMLWebViewElement.Source = new Uri("ms-appx-web:///Pages/default.html");

Per uno degli scenari illustrati in questi esempi, usare l'overload del costruttore Uri che deduce UriKind. Specificare un URI assoluto valido, incluso lo schema e l'autorità, oppure lasciare che l'autorità per impostazione predefinita sia il pacchetto dell'app come nell'esempio precedente.

Si noti che in questi URI di esempio lo schema ("ms-appx" o "ms-appx-web") è seguito da "://" seguito da un percorso assoluto. In un percorso assoluto, il "/" iniziale fa in modo che il percorso venga interpretato dalla radice del pacchetto.

Nota

Gli schemi ms-resource (per le risorse stringa) e ms-appx(-web) (per immagini e altri asset) eseguono la corrispondenza automatica dei qualificatori per trovare la risorsa più appropriata per il contesto corrente. Lo ms-appdata schema URI (usato per caricare i dati dell'app) non esegue tali corrispondenze automatiche, ma è possibile rispondere al contenuto di ResourceContext.QualifierValues e caricare in modo esplicito gli asset appropriati dai dati dell'app usando il nome di file fisico completo nell'URI. Per altre info sui dati dell'applicazione, vedi Archiviare e recuperare le impostazioni e altri dati dell'app. Gli schemi URI Web (ad esempio, http, httpse ftp) non eseguono tali corrispondenze automatiche. Per informazioni sulle operazioni da eseguire in questo caso, vedere Hosting e caricamento di immagini nel cloud.

I percorsi assoluti sono una buona scelta se i file di immagine rimangono nella struttura del progetto. Se vuoi essere in grado di spostare un file di immagine, ma fai attenzione che rimanga nella stessa posizione rispetto al relativo file di markup XAML di riferimento, invece di un percorso assoluto potresti voler usare un percorso relativo al file di markup contenitore. In questo caso, non è necessario usare uno schema URI. In questo caso potrai comunque trarre vantaggio dalla corrispondenza automatica dei qualificatori, ma solo perché usi il percorso relativo nel markup XAML.

<Image Source="Assets/Images/logo.png"/>

Vedi anche Supporto delle notifiche di riquadri e avvisi popup per lingua, fattore di scala e contrasto elevato.

Qualificare una risorsa immagine per l'destinazioni

È possibile usare i scale qualificatori e targetsize in varianti diverse della stessa risorsa immagine, ma non è possibile usarle entrambe in una singola variante di una risorsa. Inoltre, è necessario definire almeno una variante senza un TargetSize qualificatore. Tale variante deve definire un valore per scaleo lasciare che l'impostazione predefinita sia scale-100. Quindi, queste due varianti della /Assets/Square44x44Logo.png risorsa sono valide.

\Assets\Square44x44Logo.scale-200.png
\Assets\Square44x44Logo.targetsize-24.png

E queste due varianti sono valide.

\Assets\Square44x44Logo.png // defaults to scale-100
\Assets\Square44x44Logo.targetsize-24.png

Ma questa variante non è valida.

\Assets\Square44x44Logo.scale-200_targetsize-24.png

Fare riferimento a un file di immagine dal manifesto del pacchetto dell'app

Se si denominano cartelle e/o file come in uno dei due esempi validi nella sezione precedente, si dispone di una singola risorsa immagine icona dell'app e il relativo nome (come percorso relativo) è Assets\Square44x44Logo.png. Nel manifesto del pacchetto dell'app è sufficiente fare riferimento alla risorsa in base al nome. Non è necessario usare uno schema URI.

add resource, english

È sufficiente eseguire questa operazione e il sistema operativo eseguirà la corrispondenza automatica dei qualificatori per trovare la risorsa più appropriata per il contesto corrente. Per un elenco di tutti gli elementi nel manifesto del pacchetto dell'app che puoi localizzare o qualificare in questo modo, vedi Elementi del manifesto localizzabili.

Qualificare una risorsa immagine per layoutdirection

Vedi Immagini di mirroring.

Caricare un'immagine per una lingua specifica o un altro contesto

Per altre informazioni sulla proposta di valore associata alla localizzazione dell'app, vedi Globalizzazione e localizzazione.

Il valore predefinito ResourceContext (ottenuto da ResourceContext.GetForCurrentView) contiene un valore qualificatore per ogni nome qualificatore, che rappresenta il contesto di runtime predefinito (in altre parole, le impostazioni per l'utente e il computer correnti). I file immagine vengono confrontati, in base ai qualificatori nei nomi, rispetto ai valori qualificatori nel contesto di runtime.

In alcuni casi, tuttavia, potrebbe essere necessario che l'app eserciti l'override delle impostazioni di sistema ed essere espliciti sul linguaggio, la scalabilità o un altro valore qualificatore da usare quando si cerca un'immagine corrispondente da caricare. Ad esempio, è possibile controllare esattamente quando e quali immagini a contrasto elevato vengono caricate.

A tale scopo, è possibile costruire un nuovo Oggetto ResourceContext (anziché usare quello predefinito), eseguire l'override dei relativi valori e quindi usare tale oggetto di contesto nelle ricerche di immagini.

var resourceContext = new Windows.ApplicationModel.Resources.Core.ResourceContext(); // not using ResourceContext.GetForCurrentView 
resourceContext.QualifierValues["Contrast"] = "high";
var namedResource = Windows.ApplicationModel.Resources.Core.ResourceManager.Current.MainResourceMap[@"Files/Assets/Logo.png"];
var resourceCandidate = namedResource.Resolve(resourceContext);
var imageFileStream = resourceCandidate.GetValueAsStreamAsync().GetResults();
var bitmapImage = new Windows.UI.Xaml.Media.Imaging.BitmapImage();
bitmapImage.SetSourceAsync(imageFileStream);
this.myXAMLImageElement.Source = bitmapImage;

Per raggiungere lo stesso effetto a livello globale, è possibile eseguire l'override dei valori del qualificatore nell'oggetto ResourceContext predefinito. Ma ti consigliamo di chiamare ResourceContext.SetGlobalQualifierValue. I valori vengono impostati una volta con una chiamata a SetGlobalQualifierValue e quindi tali valori sono applicati al valore predefinito ResourceContext ogni volta che viene usato per le ricerche. Per impostazione predefinita, la classe ResourceManager usa l'oggetto ResourceContext predefinito.

Windows.ApplicationModel.Resources.Core.ResourceContext.SetGlobalQualifierValue("Contrast", "high");
var namedResource = Windows.ApplicationModel.Resources.Core.ResourceManager.Current.MainResourceMap[@"Files/Assets/Logo.png"];
this.myXAMLImageElement.Source = new Windows.UI.Xaml.Media.Imaging.BitmapImage(namedResource.Uri);

Aggiornamento delle immagini in risposta agli eventi di modifica del valore qualificatore

L'app in esecuzione può rispondere alle modifiche nelle impostazioni di sistema che influiscono sui valori del qualificatore nel contesto della risorsa predefinito. Una di queste impostazioni di sistema richiama l'evento MapChanged in ResourceContext.QualifierValues.

In risposta a questo evento, è possibile ricaricare le immagini con l'aiuto dell'oggetto ResourceContext predefinito, usato da ResourceManager per impostazione predefinita.

public MainPage()
{
    this.InitializeComponent();

    ...

    // Subscribe to the event that's raised when a qualifier value changes.
    var qualifierValues = Windows.ApplicationModel.Resources.Core.ResourceContext.GetForCurrentView().QualifierValues;
    qualifierValues.MapChanged += new Windows.Foundation.Collections.MapChangedEventHandler<string, string>(QualifierValues_MapChanged);
}

private async void QualifierValues_MapChanged(IObservableMap<string, string> sender, IMapChangedEventArgs<string> @event)
{
    var dispatcher = this.myImageXAMLElement.Dispatcher;
    if (dispatcher.HasThreadAccess)
    {
        this.RefreshUIImages();
    }
    else
    {
        await dispatcher.RunAsync(Windows.UI.Core.CoreDispatcherPriority.Normal, () => this.RefreshUIImages());
    }
}

private void RefreshUIImages()
{
    var namedResource = Windows.ApplicationModel.Resources.Core.ResourceManager.Current.MainResourceMap[@"Files/Assets/Logo.png"];
    this.myImageXAMLElement.Source = new Windows.UI.Xaml.Media.Imaging.BitmapImage(namedResource.Uri);
}

API importanti