Condividi tramite


Localizzare le stringhe nell'interfaccia utente e nel manifesto del pacchetto dell'app

Per altre informazioni sulla proposta di valore associata alla localizzazione dell'app Windows App SDK, vedere Globalizzazione e localizzazione.

Se vuoi supportare lingue di visualizzazione diverse nell'app e hai stringhe letterali nel codice o nel markup XAML oppure nel manifesto del pacchetto dell'app, sposta le stringhe in un file di risorse (con estensione resw). Puoi quindi creare una copia tradotta del file di risorse per ogni lingua supportata dall'app.

Le stringhe letterali incorporate possono apparire nel codice imperativo o nel markup XAML, ad esempio nell'ambito della proprietà Text di un TextBlock. Possono anche essere visualizzati nel file di origine del manifesto del pacchetto dell'app (il file Package.appxmanifest), ad esempio come valore per Nome visualizzato nella scheda Applicazione di Manifest Designer di Visual Studio. Spostare queste stringhe in un file di risorse (con estensione resw), e sostituire i valori letterali di stringa codificati nell'app e nello manifesto con riferimenti agli identificatori di risorsa.

A differenza delle risorse immagine, in cui è contenuta una sola risorsa immagine in un file di risorse immagine, più risorse stringa sono contenute in un file di risorse stringa. Un file di risorse stringa è un file di risorse (con estensione resw) e in genere si crea questo tipo di file di risorse in una cartella \Strings nel progetto. Per informazioni su come usare qualificatori nei nomi dei file di risorse (con estensione resw), vedere Adattare le risorse per lingua, scalabilità e altri qualificatori.

Archiviare stringhe in un file di risorse

  1. Impostare la lingua predefinita dell'app.

    1. Con la soluzione aperta in Visual Studio, apri Package.appxmanifest.
    2. Nella scheda Applicazione verificare che la lingua predefinita sia impostata in modo appropriato , ad esempio "en" o "en-US". I passaggi rimanenti presuppongono che sia stata impostata la lingua predefinita su "en-US".

    Nota

    È necessario specificare almeno le risorse stringa localizzate per questa lingua predefinita. Si tratta delle risorse che verranno caricate se non è possibile trovare una corrispondenza migliore per la lingua preferita dell'utente o le impostazioni della lingua di visualizzazione.

  2. Creare un file di risorse (con estensione resw) per la lingua predefinita.

    1. Nel nodo del progetto crea una nuova cartella e assegnale il nome Strings.
    2. In Stringscreare una nuova sottocartella e denominarla en-US.
    3. Alla voce en-US, creare un nuovo file di risorse (con estensione resw) (nei tipi di file WinUI della finestra di dialogo Aggiungi nuovo elemento ) e verificare che sia denominato Resources.resw.

    Nota

    Se sono presenti file di risorse .NET (con estensione resx) da convertire, vedi Conversione di XAML e interfaccia utente.

  3. Apri Resources.resw e aggiungi queste risorse di stringhe.

    Strings/en-US/Resources.resw

    Screenshot della tabella 'Add Resource' del file Strings > E N U S > Resources.resw.

    In questo esempio "Greeting" è un identificatore di risorsa stringa a cui è possibile fare riferimento dal markup, come verrà mostrato. Per l'identificatore "Greeting", viene fornita una stringa per una proprietà Text e viene fornita una stringa per una proprietà Width. "Greeting.Text" è un esempio di identificatore di proprietà perché corrisponde a una proprietà di un elemento dell'interfaccia utente. È anche possibile, ad esempio, aggiungere "Greeting.Foreground" nella colonna Name e impostarne Value su "Red". L'identificatore "Addio" è un identificatore di risorsa stringa semplice; non ha sottoproprietà e può essere caricata dal codice imperativo, come verrà mostrato. La colonna Comment è un buon posto per fornire istruzioni speciali ai traduttori.

    In questo esempio, poiché è presente una semplice voce di identificatore di risorsa stringa denominata "Farewell", non è possibile avere anche identificatori di proprietà basati sullo stesso identificatore. L'aggiunta di "Farewell.Text" provocherebbe quindi un errore di voce duplicata durante la compilazione Resources.resw.

    Gli identificatori di risorsa non fanno distinzione tra maiuscole e minuscole e devono essere univoci per ogni file di risorse. Assicurarsi di usare identificatori di risorsa significativi per fornire contesto aggiuntivo per i traduttori. E non modificare gli identificatori di risorsa dopo l'invio delle stringhe di risorse per la traduzione. I team di localizzazione usano l'identificatore della risorsa per tenere traccia di aggiunte, eliminazioni e aggiornamenti nelle risorse. Le modifiche apportate agli identificatori di risorsa, note anche come "spostamento degli identificatori di risorsa", richiedono la ritraslazione delle stringhe, perché verranno visualizzate come se le stringhe siano state eliminate e altre aggiunte.

Fare riferimento a un identificatore di risorsa di testo da XAML

Si usa una direttiva x:Uid per associare un controllo o un altro elemento nel markup a un identificatore di risorsa stringa.

<TextBlock x:Uid="Greeting"/>

In fase di esecuzione, \Strings\en-US\Resources.resw viene caricato (dal momento che è l'unico file di risorse nel progetto). La direttiva x:Uid in TextBlock determina l'esecuzione di una ricerca, per trovare gli identificatori di proprietà all'interno Resources.resw che contengono l'identificatore di risorsa stringa "Greeting". Vengono trovati gli identificatori di proprietà "Greeting.Text" e "Greeting.Width" e i relativi valori vengono applicati a TextBlock , eseguendo l'override di tutti i valori impostati localmente nel markup. Il valore "Greeting.Foreground" verrebbe applicato anche se l'avessi aggiunto. Ma solo gli identificatori di proprietà vengono usati per impostare le proprietà sugli elementi di markup XAML, quindi l'impostazione di x:Uid su "Farewell" su questo TextBlock non avrà alcun effetto. Resources.resw contiene l'identificatore di risorsa stringa "Farewell", ma non contiene identificatori di proprietà per esso.

Quando si assegna un identificatore di risorsa stringa a un elemento XAML, assicurarsi che tutti gli identificatori di proprietà per tale identificatore siano appropriati per l'elemento XAML. Ad esempio, se si imposta x:Uid="Greeting" su un textBlock , "Greeting.Text" verrà risolto perché il tipo TextBlock ha una proprietà Text. Tuttavia, se si imposta x:Uid="Greeting" su un pulsante , "Greeting.Text" genererà un errore di run-time perché il tipo Button non dispone di una proprietà Text. Una soluzione per questo caso consiste nell'creare un identificatore di proprietà denominato "ButtonGreeting.Content" e impostare x:Uid="ButtonGreeting" su Button.

Invece di impostare Width da un file di risorse, è probabile che si voglia consentire ai controlli di ridimensionare dinamicamente il contenuto.

Nota

Per le Proprietà associate, è necessaria una sintassi speciale nella colonna Nome di un file con estensione resw. Ad esempio, per impostare un valore per la proprietà associata AutomationProperties.Name per l'identificatore "Greeting", si tratta di ciò che si immette nella colonna Nome.

Greeting.[using:Microsoft.UI.Xaml.Automation]AutomationProperties.Name

Fare riferimento a un identificatore di risorsa stringa nel codice

È possibile caricare in modo esplicito una risorsa stringa in base a un identificatore di risorsa stringa semplice.

var resourceLoader = new Microsoft.Windows.ApplicationModel.Resources.ResourceLoader();
this.myXAMLTextBlockElement.Text = resourceLoader.GetString("Farewell");

È possibile usare lo stesso codice dall'interno di un progetto libreria di classi. In fase di esecuzione, vengono caricate le risorse dell'app che ospita la libreria. È consigliabile che una libreria carichi le risorse dall'app che la ospita, poiché è probabile che l'app abbia un livello di localizzazione maggiore. Se una libreria deve fornire risorse, deve fornire all'app di hosting l'opzione per sostituire tali risorse come input.

Se un nome di risorsa è segmentato (contiene caratteri ".", sostituire i punti con i caratteri barra ("/") nel nome della risorsa. Gli identificatori di proprietà, ad esempio, contengono punti; è quindi necessario eseguire questa sostituzione per caricare uno di questi dal codice.

this.myXAMLTextBlockElement.Text = resourceLoader.GetString("Fare/Well"); // <data name="Fare.Well" ...> ...

In caso di dubbio, puoi usare MakePri.exe per eseguire il dump del file PRI dell'app. Ogni risorsa uri viene visualizzata nel file di dump.

<ResourceMapSubtree name="Fare"><NamedResource name="Well" uri="ms-resource://<GUID>/Resources/Fare/Well">...

Fare riferimento a un identificatore di risorsa stringa nel file manifesto del pacchetto dell'applicazione

  1. Apri il file di origine del manifesto del pacchetto dell'app (il file Package.appxmanifest), in cui per impostazione predefinita l'app è espressa come valore letterale di stringa Display name.

    Schermata del file Package.appxmanifest che mostra la scheda Applicazione con il nome visualizzato impostato su Adventure Works Cycles.

  2. Per rendere una versione localizzabile di questa stringa, aprire Resources.resw e aggiungere una nuova risorsa stringa con il nome "AppDisplayName" e il valore "Adventure Works Cycles".

  3. Sostituire il valore letterale stringa nome visualizzato con un riferimento all'identificatore di risorsa stringa appena creato ("AppDisplayName"). A tale scopo, usare lo ms-resource schema URI (Uniform Resource Identifier).

    Screenshot del file Package.appxmanifest che mostra la scheda Applicazione con il nome visualizzato impostato su MS resource App Display Name.

  4. Ripetere questo processo per ogni stringa nel manifesto che si vuole localizzare. Ad esempio, il nome breve dell'app (che puoi configurare per essere visualizzato nel riquadro dell'app in Start). Per un elenco di tutti gli elementi nel manifesto del pacchetto dell'app che è possibile localizzare, vedere Elementi del manifesto localizzabili.

Localizzare le risorse di stringa

  1. Creare una copia del file di risorse (con estensione resw) per un'altra lingua.

    1. In "Strings" creare una nuova sottocartella e denominarla "de-DE" per Deutsch (Deutschland).

    Nota

    Nota Per il nome della cartella, è possibile usare qualsiasi tag di lingua BCP-47. Per informazioni dettagliate sul qualificatore di lingua e su un elenco di tag di linguaggio comuni, vedere Personalizzare le risorse per linguaggio, scalare e altri qualificatori . 2. Creare una copia di Strings/en-US/Resources.resw nella Strings/de-DE cartella.

  2. Tradurre le stringhe.

    1. Aprire Strings/de-DE/Resources.resw e convertire i valori nella colonna Valore. Non è necessario tradurre i commenti.

    Strings/de-DE/Resources.resw

    aggiungere una risorsa, tedesco

Se si preferisce, è possibile ripetere i passaggi 1 e 2 per un'altra lingua.

Strings/fr-FR/Resources.resw

aggiungi risorsa, francese

Testare l'app

Testare l'app per la lingua di visualizzazione predefinita. È quindi possibile modificare la lingua di visualizzazione in Impostazioni>Time & Language>Region & language>Languages e ripetere il test dell'app. Esamina le stringhe nella tua interfaccia utente e anche nella shell (ad esempio, nella tua barra del titolo, che è il tuo nome visualizzato, e il nome breve sui tuoi tile).

Nota

Se è possibile trovare un nome di cartella corrispondente all'impostazione della lingua di visualizzazione, viene caricato il file di risorse all'interno di tale cartella. In caso contrario, viene eseguito il fallback, terminando con le risorse per la lingua predefinita dell'app.

Factoring di stringhe in più file di risorse

È possibile mantenere tutte le stringhe in un singolo file di risorse (resw) oppure è possibile inserirle in più file di risorse. Ad esempio, potresti voler mantenere i messaggi di errore in un file di risorse, le stringhe del manifesto del pacchetto dell'app in un'altra e le stringhe dell'interfaccia utente in un terzo. Questa è l'aspetto della struttura di cartelle in questo caso.

Screenshot del pannello Soluzione che mostra la cartella Adventure Works Cycles Strings > con le cartelle e i file localizzati in tedesco, inglese U S e francese.

Per definire l'ambito di un riferimento a un identificatore di risorsa stringa a un determinato file, è sufficiente aggiungere /<resources-file-name>/ prima dell'identificatore. L'esempio di markup seguente presuppone che ErrorMessages.resw contenga una risorsa il cui nome è "PasswordTooWeak.Text" e il cui valore descrive l'errore.

<TextBlock x:Uid="/ErrorMessages/PasswordTooWeak"/>

È sufficiente aggiungere /<resources-file-name>/ prima dell'identificatore di stringa delle risorse per file di risorse diversi daResources.resw. Questo perché "Resources.resw" è il nome file predefinito, quindi questo è ciò che si presuppone se si omette un nome di file (come abbiamo fatto negli esempi precedenti in questo argomento).

L'esempio di codice seguente presuppone che ErrorMessages.resw contenga una risorsa il cui nome è "MismatchedPasswords" e il cui valore descrive l'errore.

var resourceLoader = new Microsoft.Windows.ApplicationModel.Resources.ResourceLoader("ErrorMessages");
this.myXAMLTextBlockElement.Text = resourceLoader.GetString("MismatchedPasswords");

Se si dovesse spostare la risorsa "AppDisplayName" da Resources.resw e in ManifestResources.resw, nel manifesto del pacchetto dell'app si passerebbe ms-resource:AppDisplayName a ms-resource:/ManifestResources/AppDisplayName.

Se un nome file di risorse è segmentato (contiene caratteri "."), lasciare i punti nel nome quando vi si fa riferimento. Non sostituire i punti con barre oblique ("/"), come si farebbe per un nome di risorsa.

var resourceLoader = new Microsoft.Windows.ApplicationModel.Resources.ResourceLoader("Err.Msgs");

In caso di dubbio, puoi usare MakePri.exe per eseguire il dump del file PRI dell'app. Ogni risorsa uri viene visualizzata nel file di dump.

<ResourceMapSubtree name="Err.Msgs"><NamedResource name="MismatchedPasswords" uri="ms-resource://<GUID>/Err.Msgs/MismatchedPasswords">...

Caricare una stringa per una lingua specifica o un altro contesto

Il valore predefinito ResourceContext (ottenuto durante la creazione di un ResourceLoader) contiene un valore di 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 di risorse (con estensione .resw) sono associati, in base ai qualificatori nei loro nomi, con i valori di qualificatore nel contesto di esecuzione.

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 file di risorse corrispondente da caricare. Ad esempio, è possibile che gli utenti siano in grado di selezionare una lingua alternativa per le descrizioni comando o i messaggi di errore.

A tale scopo, è possibile costruire un nuovo oggetto ResourceContext, eseguire l'override dei relativi valori e quindi usare tale oggetto di contesto nelle ricerche di stringhe. Per un esempio simile relativo all'uso delle risorse immagine, vedere Caricare un'immagine per una lingua specifica o un altro contesto.

var resourceManager = new Microsoft.Windows.ApplicationModel.Resources.ResourceManager();
var resourceContext = resourceManager.CreateResourceContext();
resourceContext.QualifierValues["Language"] = "de-DE";
var resourceMap = resourceManager.MainResourceMap.GetSubtree("Resources");
this.myXAMLTextBlockElement.Text = resourceMap.GetValue("Farewell", resourceContext).ValueAsString;

L'uso di QualifierValues come nell'esempio di codice precedente funziona per qualsiasi qualificatore. Per il caso speciale della lingua, in alternativa, è possibile eseguire questa operazione.

resourceContext.Languages = new string[] { "de-DE" };

Caricare stringhe da una libreria di classi

Le risorse stringa di una libreria di classi a cui si fa riferimento vengono in genere aggiunte in una sottocartella del pacchetto in cui vengono incluse durante il processo di compilazione. L'identificatore di risorsa di tale stringa assume in genere il formato LibraryName/ResourcesFileName/ResourceIdentifier.

Una libreria può ottenere un ResourceLoader per le proprie risorse. Ad esempio, il codice seguente illustra come una libreria o un'app a cui si fa riferimento può ottenere un ResourceLoader per le risorse di stringa della libreria.

var resourceLoader = new Microsoft.Windows.ApplicationModel.Resources.ResourceLoader("ContosoControl/Resources");
this.myXAMLTextBlockElement.Text = resourceLoader.GetString("exampleResourceName");

In caso di dubbi circa il percorso, è possibile specificare le opzioni della riga di comando MakePri.exe per eseguire il dump del file PRI del componente o della libreria. Ogni risorsa uri viene visualizzata nel file di dump.

<NamedResource name="exampleResourceName" uri="ms-resource://Contoso.Control/Contoso.Control/ReswFileName/exampleResourceName">...

Caricamento di stringhe da altri pacchetti

Le risorse per un pacchetto dell'app vengono gestite e rese accessibili tramite il ResourceMap di primo livello del pacchetto stesso, accessibile da ResourceManager. All'interno di ogni pacchetto, i vari componenti possono avere i propri sotto-alberi ResourceMap personalizzati, a cui è possibile accedere tramite ResourceMap.GetSubtree.

Un pacchetto framework può accedere alle proprie risorse con un URI di identificatore di risorsa assoluto. Per ulteriori informazioni, consultare anche schemi URI nella documentazione UWP.

Caricamento di stringhe in applicazioni non incluse nel pacchetto

A partire da Windows versione 1903 (aggiornamento di maggio 2019), le applicazioni non incluse nel pacchetto possono anche sfruttare il sistema di gestione risorse.

È sufficiente creare controlli utente/librerie di Windows App SDK e archiviare tutte le stringhe in un file di risorse . È quindi possibile fare riferimento a un identificatore di risorsa stringa da XAML, fare riferimento a un identificatore di risorsa stringa dal codice o caricare stringhe da una libreria di classi.

Per usare le risorse nelle applicazioni non in pacchetto, è necessario eseguire alcune operazioni:

  1. Usare il costruttore sovraccarico di ResourceManager per passare il nome del file dell'app con estensione .pri quando si risolvono le risorse dal codice poiché non esiste una visualizzazione predefinita in scenari non impacchettati.
  2. Usa MakePri.exe per generare manualmente il file resources.pri dell'app.
    • Eseguire makepri new /pr <PROJECTROOT> /cf <PRICONFIG> /of resources.pri
    • Il <PRICONFIG> deve omettere la sezione "<packaging>" in modo che tutte le risorse vengano raggruppate in un singolo file resources.pri. Se si usa il file di configurazione MakePri.exe predefinito creato da createconfig, è necessario eliminare manualmente la sezione "<packaging>" dopo la creazione.
    • Il file <PRICONFIG> deve contenere tutti gli indicizzatori pertinenti necessari per unire tutte le risorse del progetto in un singolo file resources.pri. Il file di configurazione predefinito MakePri.exe creato da createconfig include tutti gli indicizzatori.
    • Se non si utilizza la configurazione predefinita, assicurarsi che l'indicizzatore PRI sia abilitato (consultare la configurazione predefinita per sapere come fare) per unire i PRI trovati dai riferimenti del progetto, dai riferimenti NuGet e così via, che si trovano all'interno della radice del progetto.

      Nota

      Omettendo il /IndexName, e poiché il progetto non ha un manifesto dell'app, lo spazio dei nomi IndexName/root del file PRI viene automaticamente impostato su Applicazione, che il runtime riconosce per le app non confezionate (in questo modo si elimina la precedente dipendenza rigida dall'ID pacchetto). Quando si specificano gli URI delle risorse, i riferimenti ms-resource:/// che omettono lo spazio dei nomi radice deducono Application come spazio dei nomi radice per le app non in pacchetto (oppure è possibile specificare Application in modo esplicito come in ms-resource://Application/).

  3. Copiare il file PRI nella directory di output di compilazione del .exe
  4. Esegui il file .exe

    Nota

    Il sistema di gestione risorse usa la lingua di visualizzazione del sistema anziché l'elenco di lingue preferito dall'utente durante la risoluzione delle risorse in base alla lingua nelle app non in pacchetto. L'elenco delle lingue preferite dall'utente viene usato solo per le app incluse nel pacchetto Windows App SDK.

Importante

È necessario ricompilare manualmente i file PRI ogni volta che vengono modificate le risorse. È consigliabile usare uno script di post-compilazione che gestisce il comando MakePri.exe e copia l'output resources.pri nella directory .exe.

Localizzare un'app in pacchetto WinUI 3

Per garantire una corretta localizzazione di un'app desktop WinUI 3 in pacchetto, dichiarare ogni lingua supportata nel file package.appxmanifest del progetto. Quando si compila il progetto vengono aggiunte al manifesto dell'applicazione generato le lingue specificate (AppxManifest.xml) e usate le risorse corrispondenti.

Nota

Le app WinUI senza pacchetti (vedi Creare il primo progetto WinUI) non contengono un package.appxmanifest file, quindi non sono necessarie altre azioni dopo l'aggiunta delle risorse appropriate al progetto.

  1. Aprire .wapproj nel package.appxmanifest editor di testo e individuare la sezione indicata di seguito:

    <Resources>
        <Resource Language="x-generate"/>
    </Resources>
    
  2. Sostituire l'elemento <Resource Language="x-generate"> con <Resource /> per ogni lingua supportata. Ad esempio, il markup seguente specifica che sono disponibili le risorse localizzate "en-US" e "es-ES":

    <Resources>
        <Resource Language="en-US"/>
        <Resource Language="es-ES"/>
    </Resources>
    

API importanti

  • ApplicationModel.Resources.ResourceLoader

Vedi anche