Localizar sequências na interface do usuário e no manifesto do pacote de aplicativos

Para obter mais informações sobre a proposta de valor de localização do aplicativo SDK do Aplicativo Windows, confira Globalização e localização.

Se você deseja que o aplicativo dê suporte a diferentes idiomas de exibição e tem literais de cadeia de caracteres no código, na marcação XAML ou no manifesto do pacote do aplicativo, mova essas cadeias de caracteres para um arquivo de recursos (.resw). Em seguida, você poderá fazer uma cópia traduzida desse arquivo de recursos para cada idioma ao qual o aplicativo dê suporte.

Literais de sequência codificados podem aparecer em código imperativo ou em marcação XAML, por exemplo, como a propriedade Texto de um TextBlock. Eles também podem aparecer no arquivo de origem do manifesto do pacote do aplicativo (o arquivo Package.appxmanifest), por exemplo, como o valor para Nome de exibição na guia Aplicativo do Designer de Manifesto do Visual Studio. Mova essas sequências para um Arquivo de Recursos (.resw) e substitua os literais de sequência codificados em seu aplicativo e em seu manifesto por referências a identificadores de recursos.

Ao contrário dos recursos de imagem, em que apenas um recurso de imagem está contido em um arquivo de recurso de imagem, vários recursos de sequência estão contidos em um arquivo de recurso de sequência. Um arquivo de recurso de sequência é um Arquivo de Recursos (.resw), e você normalmente cria esse tipo de arquivo em uma pasta \Strings no projeto. Para obter informações básicas sobre como usar qualificadores nos nomes de seus arquivos de recursos (.resw), confira Personalizar seus recursos para idioma, escala e outros qualificadores.

Armazenar sequências em um arquivo de recursos

  1. Defina o idioma padrão do seu aplicativo.

    1. Com sua solução aberta no Visual Studio, abra o Package.appxmanifest.
    2. Na guia Aplicativo, confirme se o idioma padrão está definido adequadamente (por exemplo, "en" ou "en-US"). As etapas restantes pressupõem que você definiu o idioma padrão como "en-US".

    Observação

    No mínimo, é preciso fornecer recursos de cadeia de caracteres localizados para esse idioma padrão. Esses são os recursos que serão carregados se nenhuma correspondência melhor for encontrada para o idioma preferido do usuário ou as configurações de idioma de exibição.

  2. Crie um arquivo de recursos (.resw) para o idioma padrão.

    1. No nó do projeto, crie uma nova pasta e nomeie-a Strings.
    2. Em Strings, crie uma subpasta e nomeie-a en-US.
    3. Em en-US, crie um Arquivo de Recursos (.resw) (nos tipos de arquivo WinUI na caixa de diálogo Adicionar Novo Item ) e confirme se ele está nomeado Resources.resw.

    Observação

    Se você tiver arquivos de recursos do .NET (.resx) que deseja fazer portabilidade, confira Fazer portabilidade de XAML e da interface do usuário.

  3. Abra Resources.resw e inclua esses recursos de sequência.

    Strings/en-US/Resources.resw

    Captura de tela da tabela Adicionar Recurso do arquivo Strings > E N U S > Resources.resw.

    Neste exemplo, "Greeting" é um identificador de recurso de sequência que você pode consultar na sua marcação, como mostraremos a seguir. Para o identificador "Greeting", uma sequência é fornecida para uma propriedade Text e uma sequência é fornecida para uma propriedade Width. "Greeting.Text" é um exemplo de identificador de propriedade, pois corresponde a uma propriedade de um elemento da interface do usuário. Você também pode, por exemplo, adicionar "Greeting.Foreground" na coluna Nome e definir o Valor como "Vermelho". O identificador "Farewell" é um identificador de recurso de sequência simples, sem subpropriedades e que pode ser carregado a partir de código imperativo, como mostraremos a seguir. A coluna Comentário é um bom lugar para fornecer instruções especiais aos tradutores.

    Neste exemplo, como temos uma entrada de identificador de recurso de sequência simples chamada "Farewell", não podemos também ter identificadores de propriedade baseados nesse mesmo identificador. Portanto, adicionar "Farewell.Text" causaria um erro de entrada duplicada durante a compilação de Resources.resw.

    Os identificadores de recursos não diferenciam maiúsculas de minúsculas e devem ser exclusivos por arquivo de recurso. Use identificadores de recursos significativos para fornecer contexto adicional aos tradutores. E não altere os identificadores de recursos depois que os recursos de sequência forem enviados para tradução. As equipes de localização usam o identificador de recursos para acompanhar adições, exclusões e atualizações nos recursos. As alterações nos identificadores de recursos, também conhecidas como "mudança de identificadores de recursos", exigem que as sequências sejam retraduzidas, porque parecerá que as sequências foram excluídas e outras adicionadas.

Consultar um identificador de recurso de sequência do XAML

Use uma diretiva x:Uid para associar um controle ou outro elemento em sua marcação a um identificador de recurso de sequência.

<TextBlock x:Uid="Greeting"/>

Em tempo de execução, \Strings\en-US\Resources.resw é carregado (já que no momento esse é o único arquivo de recursos no projeto). A diretiva x:Uid em TextBlock faz com que uma pesquisa seja realizada para encontrar identificadores de propriedade dentro de Resources.resw que contenham o identificador de recurso de sequência "Greeting". Os identificadores de propriedade "Greeting.Text" e "Greeting.Width" são encontrados, e seus valores são aplicados ao TextBlock, substituindo todos os valores definidos localmente na marcação. O valor "Greeting.Foreground" também seria aplicado se você o tivesse adicionado. Mas apenas identificadores de propriedade são usados para definir propriedades em elementos de marcação XAML. Portanto, definir x:Uid como "Farewell" neste TextBlock não teria efeito. Resources.reswcontém o identificador de recurso de cadeia de caracteres "Farewell", mas não contém identificadores de propriedade para ele.

Ao atribuir um identificador de recurso de sequência a um elemento XAML, certifique-se de que todos os identificadores de propriedade desse identificador sejam apropriados para o elemento XAML. Por exemplo, se você definir x:Uid="Greeting" em um TextBlock, "Greeting.Text" será resolvido, pois o tipo TextBlock tem uma propriedade Text. Mas se você definir x:Uid="Greeting" em um botão, "Greeting.Text" causará um erro em tempo de execução porque o tipo botão não tem uma propriedade Text. Uma solução para esse caso é criar um identificador de propriedade chamado "ButtonGreeting.Content" e definir x:Uid="ButtonGreeting" no Botão.

Em vez de definir a Largura de um Arquivo de Recursos, você provavelmente desejará permitir que os controles sejam dimensionados dinamicamente de acordo com o conteúdo.

Observação

Para propriedades anexadas, você precisa de uma sintaxe especial na coluna Nome de um arquivo .resw. Por exemplo, para definir um valor para a propriedade anexada AutomationProperties.Name para o identificador "Greeting", isso é o que você inseriria na coluna Nome.

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

Consultar um identificador de recurso de sequência a partir do código

Você pode fazer upload explicitamente de um recurso de sequência com base em um identificador de recurso de sequência simples.

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

Você pode usar esse mesmo código de dentro de um projeto de biblioteca de classes. Em runtime, os recursos do aplicativo que está hospedando a biblioteca são carregados. É recomendável que uma biblioteca carregue os recursos do aplicativo que a hospeda, pois é provável que o aplicativo tenha um maior grau de localização. Se uma biblioteca precisar fornecer recursos, ela deverá dar ao aplicativo de hospedagem a opção de substituir esses recursos como entrada.

Se um nome de recurso for segmentado (ele contém caracteres "."), substitua pontos por caracteres de barra ("/") no nome do recurso. Os identificadores de propriedade, por exemplo, contêm pontos; então, você precisaria fazer essa substituição para carregar um deles a partir do código.

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

Em caso de dúvida, você pode usar MakePri.exe para despejar o arquivo PRI do seu aplicativo. O uri de cada recurso é mostrado no arquivo despejado.

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

Consulte um identificador de recurso de sequência no manifesto do pacote do aplicativo

  1. Abra o arquivo de origem do manifesto do pacote do aplicativo (o arquivo Package.appxmanifest), no qual, por padrão, o Display name do aplicativo é expresso como um literal de cadeia de caracteres.

    Captura de tela do arquivo Package.appxmanifest mostrando a guia Aplicativo com o nome de exibição definido como Ciclos da Adventure Works.

  2. Para criar uma versão localizável dessa sequência, abra Resources.resw e adicione um novo recurso de sequência com o nome "AppDisplayName" e o valor "Adventure Works Cycles".

  3. Substitua o literal de cadeia de caracteres de nome de exibição por uma referência ao identificador de recurso de sequência que você acabou de criar ("AppDisplayName"). Use o esquema URI (“Uniform Resource Identifier”) ms-resource para fazer isso.

    Captura de tela do arquivo Package.appxmanifest mostrando a guia Aplicativo com o nome de exibição definido como Nome de exibição do aplicativo de recurso MS.

  4. Repita esse processo para cada sequência no manifesto que deseja localizar. Por exemplo, o nome curto do aplicativo (que você pode configurar para aparecer no bloco do aplicativo na tela de início). Para obter uma lista de todos os itens no manifesto do pacote do aplicativo que você pode localizar, confira Itens de manifesto localizáveis.

Localizar os recursos de sequência

  1. Faça uma cópia do Arquivo de Recursos (.resw) para outro idioma.

    1. Em "Strings", crie uma subpasta e a nomeie como "de-DE" para Deutsch (Deutschland).

    Observação

    Para o nome da pasta, você pode usar qualquer tag de idioma BCP-47. Consulte Personalizar recursos de idioma, escala e outros qualificadores para obter detalhes sobre o qualificador de idioma e uma lista de tags de idioma comuns. 2. Faça uma cópia do Strings/en-US/Resources.resw na pasta Strings/de-DE.

  2. Traduza as sequências.

    1. Abra Strings/de-DE/Resources.resw e traduza os valores na coluna Valor. Você não precisa traduzir os comentários.

    Strings/de-DE/Resources.resw

    Adicionar recurso, alemão

Se desejar, repita as etapas 1 e 2 para outro idioma.

Strings/fr-FR/Resources.resw

Adicionar recurso, francês

Testar seu aplicativo

Teste o aplicativo para seu idioma de exibição padrão. Em seguida, você pode alterar o idioma de exibição em Configurações>Hora e idioma>Região e idioma>Idiomas e testar novamente seu aplicativo. Observe as sequências na interface do usuário e também no shell (por exemplo, a barra de título, que é o nome de exibição, e o Nome curto nos blocos).

Observação

Se for possível encontrar um nome de pasta que corresponda à configuração de idioma de exibição, o Arquivo de Recursos dentro dessa pasta será carregado. Caso contrário, o fallback ocorre, terminando com os recursos para o idioma padrão do seu aplicativo.

Fatoração de sequências em vários arquivos de recursos

Você pode manter todas as sequências em um único arquivo de recursos (resw) ou fatorá-las em vários arquivos de recursos. Por exemplo, talvez você queira manter suas mensagens de erro em um arquivo de recursos, as sequências de manifesto do pacote do aplicativo em outro e as sequências da interface do usuário em um terceiro. Esta é a aparência da sua estrutura de pastas nesse caso.

Captura de tela do painel Solução mostrando a pasta Cadeias de Caracteres do Adventure Works Cycles > com pastas e arquivos de localidade em alemão, inglês dos EUA e francês.

Para definir o escopo de uma referência de identificador de recurso de sequência a um arquivo específico, basta adicionar /<resources-file-name>/ antes do identificador. O exemplo de marcação abaixo pressupõe que ErrorMessages.resw contém um recurso cujo nome é "PasswordTooWeak.Text" e cujo valor descreve o erro.

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

Você só precisa adicionar /<resources-file-name>/ antes do identificador de recurso de cadeia de caracteres para arquivos de recursos diferentes de Resources.resw. Isso ocorre porque "Resources.resw" é o nome de arquivo padrão, então é isso que se presume se você omitir um nome de arquivo (como fizemos nos exemplos anteriores neste tópico).

O exemplo de código abaixo pressupõe que ErrorMessages.resw contém um recurso cujo nome é "MismatchedPasswords" e cujo valor descreve o erro.

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

Se você fosse mover seu recurso "AppDisplayName" de Resources.resw para ManifestResources.resw, no manifesto do pacote do aplicativo, você mudaria ms-resource:AppDisplayName para ms-resource:/ManifestResources/AppDisplayName.

Se um nome de arquivo de recurso for segmentado (contém caracteres "."), deixe os pontos no nome ao referenciá-lo. Não substitua pontos por caracteres de barra ("/"), como faria para um nome de recurso.

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

Em caso de dúvida, você pode usar MakePri.exe para despejar o arquivo PRI do seu aplicativo. O uri de cada recurso é mostrado no arquivo despejado.

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

Carregar uma sequência para um idioma específico ou outro contexto

O padrão ResourceContext (obtido ao criar um ResourceLoader) contém um valor de qualificador para cada nome de qualificador, representando o contexto de runtime padrão (em outras palavras, as configurações do usuário atual e do computador). Os arquivos de recursos (.resw) são correspondidos (com base nos qualificadores em seus nomes) com os valores do qualificador nesse contexto de runtime.

Mas pode haver momentos em que você deseja que seu aplicativo substitua as configurações do sistema e seja explícito sobre o idioma, a escala ou outro valor de qualificador a ser usado ao procurar um arquivo de recursos correspondente para carregar. Por exemplo, talvez você queira que os usuários possam selecionar um idioma alternativo para dicas de ferramentas ou mensagens de erro.

Você pode fazer isso construindo um novo ResourceContext, substituindo seus valores e, em seguida, usando esse objeto de contexto em suas pesquisas de sequência.

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;

Usar QualifierValues como no exemplo de código acima funciona para qualquer qualificador. Para o caso especial de idioma, você pode fazer isso como alternativa.

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

Carregar sequências de uma biblioteca de classes

Os recursos de sequência de uma Biblioteca de Classes referenciada normalmente são adicionados a uma subpasta do pacote no qual são incluídos durante o processo de build. O identificador de recurso de tal sequência geralmente assume a forma de LibraryName/ResourcesFileName/ResourceIdentifier.

Uma biblioteca pode obter um ResourceLoader para os próprios recursos. Por exemplo, o código a seguir ilustra como uma biblioteca ou um aplicativo que faz referência a ela pode obter um ResourceLoader para os recursos de sequência da biblioteca.

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

Em caso de dúvida sobre o caminho, você pode especificar as opções de linha de comando MakePri.exe para despejar o arquivo PRI do componente ou da biblioteca. O uri de cada recurso é mostrado no arquivo despejado.

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

Carregamento de sequências de outros pacotes

Os recursos de um pacote do aplicativo são gerenciados e acessados por meio do próprio Mapa de Recursos de nível superior do pacote, que pode ser acessado pelo Gerenciador de Recursos. Dentro de cada pacote, vários componentes podem ter suas próprias subárvores de ResourceMap, que você pode acessar via ResourceMap.GetSubtree.

Um pacote de estrutura pode acessar seus próprios recursos com um URI de identificador de recurso absoluto. Confira também Esquemas de URI na documentação da UWP para obter mais informações.

Carregamento de sequências em aplicativos não empacotados

A partir da versão 1903 do Windows (atualização de maio de 2019), os aplicativos não empacotados também podem aproveitar o Sistema de Gerenciamento de Recursos.

Basta criar seus controles/bibliotecas de usuário do SDK do Aplicativo Windows e armazenar todas as sequências em um arquivo de recursos. Em seguida, você pode fazer referência a um identificador de recurso de sequência de XAML, fazer referência a um identificador de recurso de sequência de código ou carregar sequências de uma Biblioteca de Classes.

Para usar recursos em aplicativos não empacotados, é preciso realizar algumas ações:

  1. Use o construtor sobrecarregado do Gerenciador de Recursos para passar o nome de arquivo .pri do seu aplicativo ao resolver recursos do código, pois não há exibição padrão em cenários não empacotados.
  2. Use MakePri.exe para gerar manualmente o arquivo resources.pri do seu aplicativo.
    • Execute makepri new /pr <PROJECTROOT> /cf <PRICONFIG> /of resources.pri
    • O <PRICONFIG> deve omitir a seção "<empacotamento>" para que todos os recursos sejam agrupados em um único arquivo resources.pri. Se estiver usando o arquivo de configuração padrão MakePri.exe criado por createconfig, você precisará excluir a seção "<empacotamento>" manualmente depois que ela for criada.
    • O <PRICONFIG> deve conter todos os indexadores relevantes necessários para mesclar todos os recursos do seu projeto em um único arquivo resources.pri. O arquivo de configuração MakePri.exe padrão criado por createconfig inclui todos os indexadores.
    • Se você não usar a configuração padrão, verifique se o indexador PRI está habilitado (examine a configuração padrão para saber como fazer isso) para mesclar PRIs encontradas em referências de projeto, referências NuGet e assim por diante, localizadas na raiz do projeto.

      Observação

      Ao omitir /IndexName e pelo projeto não ter um manifesto do aplicativo, o namespace IndexName/root do arquivo PRI é definido automaticamente como Application, que o runtime entende como aplicativos não empacotados (isso remove a dependência física anterior da ID do pacote). Ao especificar URIs de recurso, ms-resource:/// que omitem o namespace raiz inferem Application como o namespace raiz para aplicativos não empacotados (ou você pode especificar Application explicitamente como em ms-resource://Application/).

  3. Copie o arquivo PRI para o diretório de saída de build do .exe
  4. Execute o .exe

    Observação

    O Sistema de Gerenciamento de Recursos usa o idioma de exibição do sistema em vez da lista de idiomas preferidos do usuário ao resolver recursos com base no idioma em aplicativos não empacotados. A lista de idiomas preferidos do usuário só é usada para aplicativos empacotados do SDK do Aplicativo Windows.

Importante

Você deve recriar manualmente os arquivos PRI sempre que os recursos forem modificados. Recomendamos o uso de um script pós-build que manipule o comando MakePri.exe e copie a saída resources.pri para o diretório .exe.

APIs importantes

Confira também