Compartilhar via


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 da localização do seu app usando o Windows App SDK, 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 cadeias de caracteres para um arquivo de recursos (.resw) e substitua os literais de cadeias de caracteres codificados em seu aplicativo e em seu manifesto por referências a identificadores de recursos.

Ao contrário dos recursos de imagem, onde apenas um recurso de imagem está contido em um arquivo de recurso de imagem, vários recursos de texto estão contidos em um arquivo de recurso de texto. Um arquivo de string é um Arquivo de Recursos (.resw), e você normalmente cria esse tipo de arquivo na pasta \Strings do seu 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 strings 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 novo Arquivo de Recursos (.resw) (dentro dos tipos de arquivo WinUI na caixa de diálogo Adicionar Novo Item) e confirme que 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 strings.

    Strings/en-US/Resources.resw

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

    Neste exemplo, "Greeting" é um identificador de recurso de string que você pode consultar no seu markup, como iremos mostrar. 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.

Referenciar um identificador de recurso de cadeia do XAML

Use uma diretiva x:Uid para associar um controle ou outro elemento em seu markup a um identificador de recurso de string.

<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 causa a realização de uma pesquisa para encontrar identificadores de propriedade dentro de Resources.resw que contenham o identificador de recurso de string "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.resw conté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

Referenciar um identificador de recurso de string 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 de despejo.

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

Consulte um identificador de recurso de cadeia no manifesto do pacote do seu 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 Adventure Works Cycles.

  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 string do nome de exibição por uma referência ao identificador de recurso de string 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 cadeia de caracteres no seu 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.

Adaptar os recursos de strings para o idioma/localidade

  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 Personalize seus recursos para idioma, escala e outros qualificadores para obter detalhes sobre o qualificador de idioma e uma lista de tags comuns de idioma. 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 os elementos de texto na interface do usuário e também no shell (por exemplo, a barra de título—que é seu Nome de Exibição—e o Nome Curto nos azulejos).

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 cadeias de caracteres em vários arquivos de recursos

Você pode manter todas as sequências em um único arquivo de recursos (resw) ou distribuí-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 Strings da 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 string 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 string para arquivos de recursos, exceto 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 seria o caso 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 cadeia de caracteres 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 comparados (com base nos qualificadores em seus nomes) com os valores do qualificador nesse contexto de tempo de execução.

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, substituir seus valores e, em seguida, usando esse objeto de contexto em suas pesquisas de strings. Para obter um exemplo semelhante usando recursos de imagem, consulte Carregar uma imagem para um idioma específico ou outro contexto.

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 Linguagem, você pode, alternativamente, fazer isso.

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

Carregar sequências de uma biblioteca de classes

Os recursos de strings de uma Biblioteca de Classes referenciada normalmente são adicionados a uma subpasta do pacote no qual são incluídos durante o período de construção. 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 de despejo.

<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 referenciar um identificador de recurso de cadeia de caracteres de XAML, referenciar um identificador de recurso de cadeia de caracteres no código ou carregar cadeias de caracteres 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, os usos de ms-resource:/// que omitem o namespace raiz assumem Application como o namespace raiz para apps não embalados (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.

Localizar um aplicativo empacotado do WinUI 3

Para garantir a localização adequada de um aplicativo de área de trabalho do WinUI 3 empacotado, declare cada idioma com suporte no arquivo package.appxmanifest do seu projeto. Quando você cria o projeto, os idiomas especificados são adicionados ao manifesto do aplicativo gerado (AppxManifest.xml) e os recursos correspondentes são usados.

Observação

Aplicativos WinUI não empacotados (consulte Criar seu primeiro projeto WinUI) não contêm um package.appxmanifest arquivo, portanto, nenhuma ação adicional é necessária depois de adicionar os recursos apropriados ao projeto.

  1. Abra o .wapproj no editor de texto package.appxmanifest e localize a seguinte seção:

    <Resources>
        <Resource Language="x-generate"/>
    </Resources>
    
  2. Substitua os elementos <Resource Language="x-generate"> por <Resource /> para cada um dos idiomas suportados. Por exemplo, a marcação a seguir especifica que os recursos localizados "en-US" e "es-ES" estão disponíveis:

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

APIs importantes

  • ApplicationModel.Resources.ResourceLoader

Confira também