Compartir a través de


Localización

Browse sample. Examinar la muestra.

La localización es el proceso de adaptación de una aplicación para cumplir los requisitos lingüísticos o culturales específicos de un mercado objetivo. Para llevar a cabo la localización, es posible que haya que traducir el texto y las imágenes de una aplicación a varios idiomas. Una aplicación localizada muestra automáticamente el texto traducido en función de la configuración de la referencia cultural del dispositivo:

.NET incluye un mecanismo integrado para localizar aplicaciones con archivos de recursos. Un archivo de recursos almacena texto y otro contenido como pares de nombre/valor que permiten a la aplicación recuperar el contenido de una clave proporcionada. Los archivos de recursos permiten separar el contenido localizado del código de la aplicación. Además de almacenar texto, los archivos de recursos también pueden almacenar imágenes y datos binarios. Ahora bien, los dispositivos tienen una gama de tamaños y densidades de pantalla y cada plataforma tiene funcionalidad para mostrar imágenes dependientes de la densidad. Por lo tanto, se debe usar la funcionalidad de la plataforma para localizar las imágenes en lugar de almacenar imágenes en archivos de recursos.

Para localizar una aplicación de .NET Multi-platform App UI (.NET MAUI), debes:

  1. Crear archivos de recursos para almacenar cadenas. Para obtener más información, consulta Creación de archivos de recursos para almacenar cadenas.
  2. Especificar el idioma neutro de la aplicación. Para obtener más información, consulta Especificar el idioma neutro de la aplicación.
  3. Realizar la configuración de la plataforma. Para obtener más información, consulta Ejecutar la configuración de la plataforma.
  4. Localizar el texto. Para obtener más información, consulta Localizar texto.
  5. Localizar imágenes. Para obtener más información, consulta Localizar imágenes.
  6. Localizar el nombre de la aplicación. Para obtener más información, consulta Localizar el nombre de la aplicación.
  7. Probar la localización. Para obtener más información, consulta Probar la localización.

Además, se puede especificar la dirección del diseño de una aplicación. Para obtener más información, consulta Localización de derecha a izquierda.

Creación de archivos de recursos para almacenar cadenas

Los archivos de recursos de .NET son archivos XML con una extensión .resx que se compilan en archivos de recursos binarios (.resources) durante el proceso de compilación. Normalmente, una aplicación localizada contiene un archivo de recursos predeterminado con todas las cadenas usadas en la aplicación, así como archivos de recursos para cada idioma admitido.

Los archivos de recursos contienen la siguiente información para cada elemento:

  • Nombre especifica la clave que se usa para acceder al texto en el código.
  • Valor especifica el texto traducido.
  • Comentario es un campo opcional que contiene información adicional.

Para agregar un archivo de recursos se debe usar el cuadro de diálogo Agregar nuevo elemento en Visual Studio:

Screenshot of adding a resource file in Visual Studio.

Una vez agregado el archivo, se pueden agregar filas para cada recurso de texto:

Screenshot of the default strings for the app.

La opción desplegable Modificador de acceso determina el modo en que Visual Studio genera la clase usada para acceder a los recursos. Al establecer el modificador de acceso en Público o Interno, se genera una clase generada con el nivel de accesibilidad especificado. Si el modificador de acceso se establece en Sin generación de código, no se genera un archivo de clase. El archivo de recursos predeterminado debe configurarse para generar un archivo de clase, lo que se traduce en que se agrega un archivo con la extensión .designer.cs al proyecto.

Una vez creado el archivo de recursos predeterminado, se pueden crear archivos adicionales para cada configuración regional que admita la aplicación. Cada archivo de recursos adicional debe tener el mismo nombre de archivo raíz que el archivo de recursos predeterminado, pero también debe incluir el idioma y la referencia cultural opcional en el nombre de archivo. Por ejemplo, si agregas un archivo de recursos denominado AppResources.resx, también podrás crear los archivos de recursos denominados AppResources.en-US.resx y AppResources.fr-FR.resx para incluir los recursos localizados en las referencias culturales inglés (Estados Unidos) y francés (Francia), respectivamente. Además, debes establecer el modificador de acceso para cada archivo de recursos adicional en Sin generación de código.

Al tiempo de ejecución, la aplicación intenta resolver una solicitud de recursos por orden de especificidad. Por ejemplo, si la referencia cultural del dispositivo es en-US la aplicación busca archivos de recursos por este orden:

  1. AppResources.en-US.resx
  2. AppResources.en.resx
  3. AppResources.resx (predeterminado)

En la captura de pantalla siguiente se muestra un archivo de traducción al español denominado AppResources.es.resx:

Screenshot of the Spanish strings for the app.

El archivo de recursos localizado usa los mismos valores de Nombre especificados en el archivo predeterminado, pero contiene cadenas de idioma español en la columna Valor. Además, el Modificador de acceso se establece en Sin generación de código.

Especificar el idioma neutro de la aplicación

Para que los archivos de recursos de .NET funcionen correctamente, la aplicación debe tener un idioma neutro especificado. Este es el idioma cuyos recursos van a usarse si no se encuentran recursos en una determinada referencia cultural. Especificación del idioma neutro:

  1. En el Explorador de soluciones, haz clic con el botón derecho en el proyecto de la aplicación y selecciona Propiedades.

  2. Selecciona la página de propiedades Paquete > General y selecciona el idioma y la referencia cultural adecuados en la lista desplegable Lenguaje neutro de ensamblado:

    Screenshot of setting the neutral language for the assembly.

  3. Guarde los cambios.

Como alternativa, agrega el elemento <NeutralLanguage> al primer <PropertyGroup> del archivo de proyecto y especifica la configuración regional elegida como su valor:

<NeutralLanguage>en-US</NeutralLanguage>

Advertencia

Si especificas un idioma neutro, la clase ResourceManager devuelve valores null para cualquier idioma sin un archivo de recursos. Cuando se especifica un idioma neutro, la clase ResourceManager devuelve los resultados del archivo de recursos de idioma neutro para idiomas no admitidos. Por lo tanto, se recomienda especificar siempre un idioma neutro para que el texto se muestre para idiomas no admitidos.

Ejecutar la configuración de la plataforma

Se requiere una configuración adicional en iOS, Mac Catalyst y Windows, de modo que se localicen todos los controles de .NET MAUI.

iOS y Mac Catalyst

En iOS y Mac Catalyst, debes declarar todos los idiomas admitidos en el archivo Info.plist de la plataforma del proyecto de aplicación .NET MAUI. Para ello, abre el archivo Info.plist para la plataforma elegida en un editor XML y crea una matriz para la clave CFBundleLocalizations. Después, proporciona valores de matriz que correspondan a los archivos de recursos. Además, asegúrese de establecer un idioma esperado a través de la clave CFBundleDevelopmentRegion:

<key>CFBundleLocalizations</key>
<array>
    <string>de</string>
    <string>es</string>
    <string>fr</string>
    <string>ja</string>
    <string>pt</string> <!-- Brazil -->
    <string>pt-PT</string> <!-- Portugal -->
    <string>ru</string>
    <string>zh-Hans</string>
    <string>zh-Hant</string>
</array>
<key>CFBundleDevelopmentRegion</key>
<string>en</string>

Como alternativa, en el Explorador de soluciones en Visual Studio, abre el archivo Info.plist para la plataforma elegida en el Editor de PList genérico. A continuación, crea una matriz para la clave CFBundleLocalizations y proporciona valores de matriz que corresponden a los archivos de recursos. Además, asegúrese de establecer un idioma esperado a través de la clave CFBundleDevelopmentRegion:

Screenshot of the supported locales for the app in the generic Info.plist editor.

Para obtener más información sobre el archivo Info.plist, consulta Lista de propiedades de información.

Windows

Para admitir varios idiomas en una aplicación .NET MAUI en Windows, debes declarar cada idioma admitido en el archivo Platforms\Windows\Package.appxmanifest del proyecto de aplicación .NET MAUI:

  1. Abre el archivo Package.appxmanifest en un editor de texto y busca la sección siguiente:

    <Resources>
        <Resource Language="x-generate"/>
    </Resources>
    
  2. Reemplaza <Resource Language="x-generate"> por los elementos <Resource /> de cada uno de los idiomas admitidos:

    <Resources>
        <Resource Language="en-US"/>
        <Resource Language="de-DE"/>
        <Resource Language="es-ES"/>
        <Resource Language="fr-FR"/>
        <Resource Language="ja-JP"/>
        <Resource Language="pt-BR"/>
        <Resource Language="pt-PT"/>
        <Resource Language="ru-RU"/>
        <Resource Language="zh-CN"/>
        <Resource Language="zh-TW"/>
    </Resources>
    
  3. Guarde los cambios.

Localizar texto

El texto se localiza mediante una clase generada a partir del archivo de recursos predeterminado. Esta clase se denomina según el nombre del archivo de recursos predeterminado. Con el nombre de archivo de recurso predeterminado de AppResources.resx, Visual Studio genera una clase coincidente denominada AppResources que contiene propiedades estáticas para cada entrada del archivo de recursos.

En XAML, el texto localizado se puede recuperar mediante la extensión de marcado x:Static para acceder a las propiedades estáticas generadas:

<ContentPage ...
             xmlns:strings="clr-namespace:LocalizationDemo.Resources.Strings">
    <VerticalStackLayout>
        <Label Text="{x:Static strings:AppResources.NotesLabel}" />
        <Entry Placeholder="{x:Static strings:AppResources.NotesPlaceholder}" />
        <Button Text="{x:Static strings:AppResources.AddButton}" />
    </VerticalStackLayout>
</ContentPage>

Para obtener más información acerca de la extensión de marcado x:Static, consulta Extensión de marcado x:Static.

El texto localizado también se puede recuperar con código:

Label notesLabel = new Label();
notesLabel.Text = AppResources.NotesLabel,

Entry notesEntry = new Entry();
notesEntry.Placeholder = AppResources.NotesPlaceholder,

Button addButton = new Button();
addButton.Text = AppResources.AddButton,

Las propiedades de la clase AppResources usan el valor de propiedad CurrentUICulture para determinar de qué archivo de recursos se deben recuperar los valores.

Localización de imágenes

Además de almacenar texto, los archivos de recursos también pueden almacenar imágenes y datos binarios. Ahora bien, los dispositivos tienen una gama de tamaños y densidades de pantalla y cada plataforma tiene funcionalidad para mostrar imágenes dependientes de la densidad. Por lo tanto, se debe usar la funcionalidad de la plataforma para localizar las imágenes en lugar de almacenar imágenes en archivos de recursos.

Android

En Android, las imágenes localizadas conocidas como drawables se almacenan con una convención de nomenclatura en la carpeta Platforms\Android\Resources. Las carpetas se denominan drawable con un sufijo para el idioma de destino y referencia cultural. Por ejemplo, la carpeta de idioma español se denomina drawable-es. El nombre de carpeta drawable debe contener las imágenes del idioma y la referencia cultural predeterminados. La acción de compilación de cada imagen debe establecerse en AndroidResource.

Nota:

En lugar de establecer archivos individuales en la acción de compilación AndroidResource, el contenido de una carpeta específica se puede establecer en esta acción de compilación agregando el siguiente XML al archivo del proyecto de aplicación (.csproj):

<ItemGroup Condition="$(TargetFramework.Contains('-android'))">
  <AndroidResource Include="Platforms\Android\Resources\**" TargetPath="%(RecursiveDir)%(Filename)%(Extension)" />
</ItemGroup>

En este ejemplo se establece cualquier contenido de la carpeta Platforms\Android\Resources, incluido el contenido de las subcarpetas, en la acción de compilación AndroidResource. También establece la ruta de acceso de salida de cada archivo con esta acción de compilación.

Solo se requieren dos caracteres en el nombre de carpeta al especificar un idioma de nivel superior, como es. Sin embargo, al especificar una configuración regional completa, el formato de nombre de carpeta requiere un guion y r en minúsculas para separar el idioma de la referencia cultural. Por ejemplo, la carpeta de configuración regional de México (es-MX) debe denominarse drawable-es-rMX. Los nombres de archivo de imagen de cada carpeta de configuración regional deben ser idénticos:

Screenshot of the localized folder structure in Visual Studio for images on Android.

iOS

En iOS, las imágenes localizadas se almacenan con una convención de nomenclatura para carpetas en la carpeta Platforms\iOS\Resources. Las carpetas deben denominarse con el idioma y la referencia cultural opcional, seguida de .lproj. Por ejemplo, la carpeta de idioma español se denomina es.lproj. La acción de compilación de cada imagen debe establecerse en BundleResource.

Nota:

En lugar de establecer archivos individuales en la acción de compilación BundleResource, el contenido de una carpeta específica se puede establecer en esta acción de compilación agregando el siguiente XML al archivo del proyecto de la aplicación (.csproj):

<ItemGroup Condition="$(TargetFramework.Contains('-ios'))">
  <BundleResource Include="Platforms\iOS\Resources\**" TargetPath="%(RecursiveDir)%(Filename)%(Extension)" />
</ItemGroup>

En este ejemplo se establece cualquier contenido de la carpeta Platforms\iOS\Resources, incluido el contenido de las subcarpetas, en la acción de compilación BundleResource. También establece la ruta de acceso de salida de cada archivo con esta acción de compilación.

Solo se requieren dos caracteres en el nombre de carpeta al especificar un idioma de nivel superior, como es. Sin embargo, al especificar una configuración regional completa, el formato de nombre de carpeta requiere un guion para separar el idioma de la referencia cultural. Por ejemplo, la carpeta de configuración regional de México (es-MX) debe denominarse es-MX.lproj. Los nombres de archivo de imagen de cada carpeta de configuración regional deben ser idénticos:

Screenshot of the localized folder structure in Visual Studio for images on iOS.

Además, en el archivo de proyecto debe establecer la propiedad de compilación IPhoneResourcePrefix en la carpeta que contiene las carpetas de imágenes localizadas:

<PropertyGroup Condition="$(TargetFramework.Contains('-ios'))">
  <IPhoneResourcePrefix>Platforms/iOS/Resources</IPhoneResourcePrefix>
</PropertyGroup>

Si una imagen no está presente para un idioma determinado, iOS vuelve a la carpeta de idioma nativo predeterminada y carga la imagen desde allí.

Mac Catalyst

En Mac Catalyst, las imágenes localizadas se almacenan mediante una convención de nomenclatura basada en carpetas en la carpeta Platforms\MacCatalyst\Resources. Las carpetas deben denominarse con el idioma y la referencia cultural opcional, seguida de .lproj. Por ejemplo, la carpeta de idioma español se denomina es.lproj. La acción de compilación de cada imagen debe establecerse en BundleResource.

Nota:

En lugar de establecer archivos individuales en la acción de compilación BundleResource, el contenido de una carpeta específica se puede establecer en esta acción de compilación agregando el siguiente XML al archivo del proyecto de la aplicación (.csproj):

<ItemGroup Condition="$(TargetFramework.Contains('-maccatalyst'))">
  <BundleResource Include="Platforms\MacCatalyst\Resources\**" TargetPath="%(RecursiveDir)%(Filename)%(Extension)" />
</ItemGroup>

En este ejemplo se establece cualquier contenido de la carpeta Platforms\MacCatalyst\Resources, incluido el contenido de las subcarpetas, en la acción de compilación BundleResource. También establece la ruta de acceso de salida de cada archivo con esta acción de compilación.

Solo se requieren dos caracteres en el nombre de carpeta al especificar un idioma de nivel superior, como es. Sin embargo, al especificar una configuración regional completa, el formato de nombre de carpeta requiere un guion para separar el idioma de la referencia cultural. Por ejemplo, la carpeta de configuración regional de México (es-MX) debe denominarse es-MX.lproj. Los nombres de archivo de imagen de cada carpeta de configuración regional deben ser idénticos:

Screenshot of the localized folder structure in Visual Studio for images on MacCatalyst.

Además, en el archivo de proyecto debe establecer la propiedad de compilación IPhoneResourcePrefix en la carpeta que contiene las carpetas de imágenes localizadas:

<PropertyGroup Condition="$(TargetFramework.Contains('-maccatalyst'))">
  <IPhoneResourcePrefix>Platforms/MacCatalyst/Resources</IPhoneResourcePrefix>
</PropertyGroup>

Si una imagen no está presente para un idioma determinado, Mac Catalyst vuelve a la carpeta de idioma nativo predeterminada y carga la imagen desde allí.

Windows

En Windows, las imágenes localizadas se almacenan con una convención de nomenclatura para carpetas en la carpeta Assets/Images. Las carpetas deben denominarse con el idioma y la referencia cultural opcional. Por ejemplo, la carpeta de idioma español se denomina es y la carpeta de configuración regional de México debe tener el nombre es-MX. La acción de compilación de cada imagen debe establecerse en Contenido.

Nota:

En lugar de establecer archivos individuales en la acción de compilación de contenido, el contenido de una carpeta específica se puede establecer en esta acción de compilación agregando el siguiente XML al archivo del proyecto de la aplicación (.csproj):

<ItemGroup Condition="$(TargetFramework.Contains('-windows'))">
  <Content Include="Platforms\Windows\Assets\Images\**" TargetPath="%(RecursiveDir)%(Filename)%(Extension)" />
</ItemGroup>

En este ejemplo se establece cualquier contenido de la carpeta Plataforms\Windows\Assets\Images, incluido el contenido de las subcarpetas, en la acción compilación de contenido. También establece la ruta de acceso de salida de cada archivo con esta acción de compilación.

Solo se requieren dos caracteres en el nombre de carpeta al especificar un idioma de nivel superior, como es. Sin embargo, al especificar una configuración regional completa, el formato de nombre de carpeta requiere un guion para separar el idioma de la referencia cultural. Por ejemplo, la carpeta de configuración regional de México (es-MX) debe denominarse es-MX. Los nombres de archivo de imagen de cada carpeta de configuración regional deben ser idénticos:

Screenshot of the localized folder structure in Visual Studio for images on Windows.

Consumo de imágenes localizadas

En Android, iOS, Mac Catalyst y Windows, las imágenes localizadas se pueden consumir estableciendo la propiedad Source de Image en el nombre de archivo de imagen:

<Image Source="flag.png" />

Sin embargo, para que esto funcione en Windows, es necesario modificar el archivo de proyecto de la aplicación si has agregado un elemento <Content /> de MSBuild para cada imagen localizada. Esto se puede lograr modificando el archivo .csproj para quitar el elemento <Content /> de MSBuild de cada imagen. A continuación, agrega el siguiente elemento de MSBuild:

<ItemGroup Condition="$(TargetFramework.Contains('-windows'))">
  <Content Include="Platforms\Windows\Assets\Images\**" TargetPath="%(RecursiveDir)%(Filename)%(Extension)" />
</ItemGroup>

Esto garantiza que todas las imágenes de las subcarpetas de la carpeta Platforms\Windows\Assets\Images se copien en la raíz del paquete de la aplicación.

Localizar el nombre de la aplicación

La funcionalidad de la plataforma es necesaria para localizar el nombre de la aplicación.

Android

En Android, el nombre de la aplicación localizada se puede almacenar mediante una convención de nomenclatura basada en carpetas en la carpeta Platforms\Android\Resources. Las carpetas deben tener valores con nombre con un sufijo para el idioma y la referencia cultural. Por ejemplo, la carpeta de idioma español se denomina values-es. Agrega un archivo Strings.xml con una acción de compilación de AndroidResource a cada carpeta que establezcas una cadena en el nombre de la aplicación localizada.

Nota:

En lugar de establecer archivos individuales en la acción de compilación AndroidResource, el contenido de una carpeta específica se puede establecer en esta acción de compilación agregando el siguiente XML al archivo del proyecto de aplicación (.csproj):

<ItemGroup Condition="$(TargetFramework.Contains('-android'))">
  <AndroidResource Include="Platforms\Android\Resources\**" TargetPath="%(RecursiveDir)%(Filename)%(Extension)" />
</ItemGroup>

En este ejemplo se establece cualquier contenido de la carpeta Platforms\Android\Resources, incluido el contenido de las subcarpetas, en la acción de compilación AndroidResource. También establece la ruta de acceso de salida de cada archivo con esta acción de compilación.

Solo se requieren dos caracteres en el nombre de carpeta al especificar un idioma de nivel superior, como es. Sin embargo, al especificar una configuración regional completa, el formato de nombre de carpeta requiere un guion y r en minúsculas para separar el idioma de la referencia cultural. Por ejemplo, la carpeta de configuración regional de México (es-MX) debe denominarse values-es-rMX.

Cada cadena traducible es un elemento XML con el identificador de recurso especificado como atributo name y la cadena traducida como valor. Debes ejecutar el escape de la cadena según las reglas XML normales y name debe ser un identificador de recurso de Android válido (sin espacios ni guiones).

Por lo tanto, para localizar el nombre de la aplicación, crea un archivo Strings.xml y agrega un elemento <string> como elemento secundario de un elemento <resources>. A continuación, establece su atributo name en un identificador adecuado con la cadena traducida como valor:

<resources>
    <!-- French -->
    <string name="app_name">Maison</string>
</resources>

A continuación, para usar el nombre de la aplicación localizado en la aplicación, agrega la propiedad Label a Activity en la clase MainActivity de la aplicación y establece su valor en @string/id:

[Activity(Label = "@string/app_name", Theme = "@style/Maui.SplashTheme", MainLauncher = true, ConfigurationChanges = ConfigChanges.ScreenSize | ConfigChanges.Orientation | ConfigChanges.UiMode | ConfigChanges.ScreenLayout | ConfigChanges.SmallestScreenSize | ConfigChanges.Density)]
public class MainActivity : MauiAppCompatActivity
{
    protected override void OnCreate(Bundle savedInstanceState)
    {
        base.OnCreate(savedInstanceState);
    }
}

iOS

En iOS, el nombre de la aplicación localizado se almacena mediante una convención de nomenclatura basada en carpetas en la carpeta Platforms\iOS\Resources. Las carpetas deben denominarse con el idioma y la referencia cultural opcional, seguida de .lproj. Por ejemplo, la carpeta de idioma español se denomina es.lproj. Agrega un archivo InfoPlist.strings con una acción de compilación de BundleResource a cada carpeta que establezca la clave CFBundleDisplayName y el valor.

Nota:

En lugar de establecer archivos individuales en la acción de compilación BundleResource, el contenido de una carpeta específica se puede establecer en esta acción de compilación agregando el siguiente XML al archivo del proyecto de la aplicación (.csproj):

<ItemGroup Condition="$(TargetFramework.Contains('-ios'))">
  <BundleResource Include="Platforms\iOS\Resources\**" TargetPath="%(RecursiveDir)%(Filename)%(Extension)" />
</ItemGroup>

En este ejemplo se establece cualquier contenido de la carpeta Platforms\iOS\Resources, incluido el contenido de las subcarpetas, en la acción de compilación BundleResource. También establece la ruta de acceso de salida de cada archivo con esta acción de compilación.

La sintaxis de los valores de cadena localizados es:

/* comment */
"key"="localized-value";

Debes ejecutar el escape de los siguientes caracteres en cadenas:

  • Presupuesto de \"
  • \\ barra diagonal inversa
  • \n línea nueva

Por lo tanto, para localizar el nombre de la aplicación, crea un archivo InfoPlist.strings y agrega un valor para la clave CFBundleDisplayName al archivo:

/* French */
CFBundleDisplayName="Maisons";

Otras claves que puedes usar para localizar cadenas específicas de la aplicación son:

  • CFBundleName: especifica el nombre corto del lote de aplicaciones, que puede mostrarse a los usuarios en situaciones como la ausencia de un valor para CFBundleDisplayName.
  • CFBundleShortVersionString: especifica el número de versión del lote de aplicaciones.
  • NSHumanReadableCopyright: el aviso de copyright para el lote de aplicaciones.

Además, en el archivo de proyecto debe establecer la propiedad de compilación IPhoneResourcePrefix en la carpeta que contiene las carpetas localizadas:

<PropertyGroup Condition="$(TargetFramework.Contains('-ios'))">
  <IPhoneResourcePrefix>Platforms/iOS/Resources</IPhoneResourcePrefix>
</PropertyGroup>

Mac Catalyst

En Mac Catalyst, el nombre de la aplicación localizada se almacena mediante una convención de nomenclatura basada en carpetas en la carpeta Platforms\MacCatalyst\Resources. Las carpetas deben denominarse con el idioma y la referencia cultural opcional, seguida de .lproj. Por ejemplo, la carpeta de idioma español se denomina es.lproj. Agrega un archivo InfoPlist.strings con una acción de compilación de BundleResource a cada carpeta que establezca la clave CFBundleDisplayName y el valor.

Nota:

En lugar de establecer archivos individuales en la acción de compilación BundleResource, el contenido de una carpeta específica se puede establecer en esta acción de compilación agregando el siguiente XML al archivo del proyecto de la aplicación (.csproj):

<ItemGroup Condition="$(TargetFramework.Contains('-maccatalyst'))">
  <BundleResource Include="Platforms\MacCatalyst\Resources\**" TargetPath="%(RecursiveDir)%(Filename)%(Extension)" />
</ItemGroup>

En este ejemplo se establece cualquier contenido de la carpeta Platforms\MacCatalyst\Resources, incluido el contenido de las subcarpetas, en la acción de compilación BundleResource. También establece la ruta de acceso de salida de cada archivo con esta acción de compilación.

La sintaxis de los valores de cadena localizados es:

/* comment */
"key"="localized-value";

Debes ejecutar el escape de los siguientes caracteres en cadenas:

  • Presupuesto de \"
  • \\ barra diagonal inversa
  • \n línea nueva

Por lo tanto, para localizar el nombre de la aplicación, crea un archivo InfoPlist.strings y agrega un valor para la clave CFBundleDisplayName al archivo:

/* French */
CFBundleDisplayName="Maisons";

Otras claves que puedes usar para localizar cadenas específicas de la aplicación son:

  • CFBundleName: especifica el nombre corto del lote de aplicaciones, que puede mostrarse a los usuarios en situaciones como la ausencia de un valor para CFBundleDisplayName.
  • CFBundleShortVersionString: especifica el número de versión del lote de aplicaciones.
  • NSHumanReadableCopyright: el aviso de copyright para el lote de aplicaciones.

Además, en el archivo de proyecto debe establecer la propiedad de compilación IPhoneResourcePrefix en la carpeta que contiene las carpetas localizadas:

<PropertyGroup Condition="$(TargetFramework.Contains('-maccatalyst'))">
  <IPhoneResourcePrefix>Platforms/MacCatalyst/Resources</IPhoneResourcePrefix>
</PropertyGroup>

Windows

En Windows, el nombre de la aplicación se define en el manifiesto del paquete de la aplicación. La localización del nombre de la aplicación requiere que primero especifiques el idioma predeterminado para la aplicación y, a continuación, crea un archivo de recursos de cadena para cada configuración regional que quieras admitir. El recurso de cadena que representa el nombre de aplicación localizado se puede consumir en el manifiesto del paquete de la aplicación mediante el esquema URI ms-resource.

Para obtener más información sobre cómo localizar cadenas en el manifiesto del paquete de la aplicación, consulta Localizar cadenas de la interfaz de usuario y el manifiesto del paquete de la aplicación.

Especificar el idioma predeterminado

Para localizar un nombre de aplicación, la aplicación para Windows debe tener primero un idioma predeterminado especificado. Este es el idioma cuyos recursos van a usarse si no se encuentran recursos localizados en un idioma determinado. Para especificar el idioma predeterminado:

  1. En el Exploradores de soluciones, abre Packageappxmanifest en el editor de manifiestos del paquete.

  2. En el editor de manifiestos del paquete, en la pestaña Aplicación, establece el campo Idioma predeterminado en el idioma predeterminado elegido:

    Screenshot of setting the default language of a Windows app in the package manifest.

  3. Guarde los cambios.

Como mínimo, debes proporcionar un recurso de cadena para el nombre de la aplicación para el idioma predeterminado. Este es el recurso que se carga si no se puede encontrar ninguna coincidencia mejor para el idioma preferido del usuario o la configuración de idioma para mostrar.

Creación de archivos de recursos de Windows

En Windows, el nombre de la aplicación localizada debe almacenarse en un archivo de recursos de Windows para cada configuración regional. Un archivo de recursos de Windows es un archivo XML con una extensión .resw compilada en un formato binario y almacenada en un archivo .pri. El archivo .resw para cada configuración regional debe denominarse Resources.resw y almacenarse mediante una convención de nomenclatura basada en carpetas en la carpeta Platforms\Windows\Strings. Las carpetas deben denominarse con el idioma y la referencia cultural opcional. Por ejemplo, la carpeta de idioma español se denomina es y la carpeta de configuración regional de México debe tener el nombre es-MX.

Actualmente no hay ninguna plantilla de elementos de Visual Studio para crear un archivo de recursos de Windows en una aplicación .NET MAUI. Por lo tanto, para crear un archivo de recursos de Windows para cada configuración regional:

  1. En la carpeta Plataforms\Windows del proyecto de aplicación .NET MAUI, crea una carpeta Strings.

  2. En la carpeta Strings, crea una carpeta para cada configuración regional.

  3. En la carpeta de cada configuración regional, crea un archivo denominado Resources.resw que contenga el siguiente XML:

    <?xml version="1.0" encoding="utf-8"?>
    <root>
      <!--
        Microsoft ResX Schema
    
        Version 2.0
    
        The primary goals of this format is to allow a simple XML format
        that is mostly human readable. The generation and parsing of the
        various data types are done through the TypeConverter classes
        associated with the data types.
    
        Example:
    
        ... ado.net/XML headers & schema ...
        <resheader name="resmimetype">text/microsoft-resx</resheader>
        <resheader name="version">2.0</resheader>
        <resheader name="reader">System.Resources.ResXResourceReader, System.Windows.Forms, ...</resheader>
        <resheader name="writer">System.Resources.ResXResourceWriter, System.Windows.Forms, ...</resheader>
        <data name="Name1"><value>this is my long string</value><comment>this is a comment</comment></data>
        <data name="Color1" type="System.Drawing.Color, System.Drawing">Blue</data>
        <data name="Bitmap1" mimetype="application/x-microsoft.net.object.binary.base64">
            <value>[base64 mime encoded serialized .NET Framework object]</value>
        </data>
        <data name="Icon1" type="System.Drawing.Icon, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
            <value>[base64 mime encoded string representing a byte array form of the .NET Framework object]</value>
            <comment>This is a comment</comment>
        </data>
    
        There are any number of "resheader" rows that contain simple
        name/value pairs.
    
        Each data row contains a name, and value. The row also contains a
        type or mimetype. Type corresponds to a .NET class that support
        text/value conversion through the TypeConverter architecture.
        Classes that don't support this are serialized and stored with the
        mimetype set.
    
        The mimetype is used for serialized objects, and tells the
        ResXResourceReader how to depersist the object. This is currently not
        extensible. For a given mimetype the value must be set accordingly:
    
        Note - application/x-microsoft.net.object.binary.base64 is the format
        that the ResXResourceWriter will generate, however the reader can
        read any of the formats listed below.
    
        mimetype: application/x-microsoft.net.object.binary.base64
        value   : The object must be serialized with
                : System.Runtime.Serialization.Formatters.Binary.BinaryFormatter
                : and then encoded with base64 encoding.
    
        mimetype: application/x-microsoft.net.object.soap.base64
        value   : The object must be serialized with
                : System.Runtime.Serialization.Formatters.Soap.SoapFormatter
                : and then encoded with base64 encoding.
    
        mimetype: application/x-microsoft.net.object.bytearray.base64
        value   : The object must be serialized into a byte array
                : using a System.ComponentModel.TypeConverter
                : and then encoded with base64 encoding.
        -->
      <xsd:schema id="root" xmlns="" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata">
        <xsd:import namespace="http://www.w3.org/XML/1998/namespace" />
        <xsd:element name="root" msdata:IsDataSet="true">
          <xsd:complexType>
            <xsd:choice maxOccurs="unbounded">
              <xsd:element name="metadata">
                <xsd:complexType>
                  <xsd:sequence>
                    <xsd:element name="value" type="xsd:string" minOccurs="0" />
                  </xsd:sequence>
                  <xsd:attribute name="name" use="required" type="xsd:string" />
                  <xsd:attribute name="type" type="xsd:string" />
                  <xsd:attribute name="mimetype" type="xsd:string" />
                  <xsd:attribute ref="xml:space" />
                </xsd:complexType>
              </xsd:element>
              <xsd:element name="assembly">
                <xsd:complexType>
                  <xsd:attribute name="alias" type="xsd:string" />
                  <xsd:attribute name="name" type="xsd:string" />
                </xsd:complexType>
              </xsd:element>
              <xsd:element name="data">
                <xsd:complexType>
                  <xsd:sequence>
                    <xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
                    <xsd:element name="comment" type="xsd:string" minOccurs="0" msdata:Ordinal="2" />
                  </xsd:sequence>
                  <xsd:attribute name="name" type="xsd:string" use="required" msdata:Ordinal="1" />
                  <xsd:attribute name="type" type="xsd:string" msdata:Ordinal="3" />
                  <xsd:attribute name="mimetype" type="xsd:string" msdata:Ordinal="4" />
                  <xsd:attribute ref="xml:space" />
                </xsd:complexType>
              </xsd:element>
              <xsd:element name="resheader">
                <xsd:complexType>
                  <xsd:sequence>
                    <xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
                  </xsd:sequence>
                  <xsd:attribute name="name" type="xsd:string" use="required" />
                </xsd:complexType>
              </xsd:element>
            </xsd:choice>
          </xsd:complexType>
        </xsd:element>
      </xsd:schema>
      <resheader name="resmimetype">
        <value>text/microsoft-resx</value>
      </resheader>
      <resheader name="version">
        <value>2.0</value>
      </resheader>
      <resheader name="reader">
        <value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
      </resheader>
      <resheader name="writer">
        <value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
      </resheader>
    </root>
    

    Nota:

    Los archivos de recursos de Windows usan una acción de compilación de PRIResource. Esta acción de compilación no necesita establecer en cada archivo .resw en una aplicación .NET MAUI, ya que se aplica implícitamente.

  4. Abre cada archivo Resources.resw y agrega un recurso de cadena que represente el nombre de la aplicación:

    Screenshot of the resw file editor in Visual Studio on Windows.

    Nota:

    Los identificadores de recursos no distinguen mayúsculas de minúsculas y deben ser únicos por archivo de recursos.

  5. Guarda cada archivo de recursos de Windows.

En la captura de pantalla siguiente se muestra un ejemplo de la estructura de archivos y carpetas necesarias:

Screenshot of the localized folder structure in Visual Studio for strings on Windows.

Consumir el nombre de la aplicación localizada

El recurso de cadena que representa el nombre de aplicación localizado se puede consumir mediante el esquema URI ms-resource:

  1. En el Exploradores de soluciones, abre Packageappxmanifest en el editor de manifiestos del paquete.

  2. En el editor de manifiestos del paquete, en la pestaña Aplicación, establece el campo Nombre en ms-resource: para mostrar seguido del nombre del recurso de cadena que identifica el nombre de la aplicación:

    Screenshot of setting the localized app name in the package manifest on Windows.

  3. Guarde los cambios.

Importante

Si los archivos .resw se almacenan en un ensamblado diferente al proyecto de aplicación .NET MAUI, tendrás que especificar una ruta de acceso completa al nombre del recurso. Esto usa el formato ms-resource:Assembly/ResourceFilename/Resource.

Localización de derecha a izquierda

La dirección de flujo, o la dirección del diseño, es la dirección en la que el ojo humano lee los elementos de la interfaz de usuario en la página. Algunos lenguajes, como el árabe y hebreo, requieren que los elementos de interfaz de usuario se distribuyan en una dirección de flujo de derecha a izquierda. Las aplicaciones .NET MAUI respetan automáticamente la dirección del flujo del dispositivo en función del idioma y la región seleccionados. Para obtener información sobre cómo recuperar la dirección del flujo del dispositivo, en función de su configuración regional, consulta Obtener la dirección del diseño.

Para invalidar la dirección del flujo de una aplicación, establece la propiedad Window.FlowDirection. Como alternativa, establece la propiedad VisualElement.FlowDirection por elemento. Esta propiedad obtiene o establece la dirección en que fluyen los elementos de interfaz de usuario dentro de cualquier elemento primario que controle su diseño, y debe establecerse en uno de los valores de enumeración FlowDirection:

  • LeftToRight
  • RightToLeft
  • MatchParent

Al establecer la propiedad FlowDirection como RightToLeft en un elemento, se establece la alineación a la derecha, el orden de lectura de derecha a izquierda y el diseño del control para que fluya de derecha a izquierda:

Advertencia

El cambio de la propiedad FlowDirection en tiempo de ejecución hace que el proceso de diseño sea costoso y que ello afecte al rendimiento.

El valor predeterminado de esta propiedad FlowDirection para un elemento es MatchParent. Por lo tanto, un elemento hereda el valor de la propiedad FlowDirection de su elemento primario en el árbol visual, y cualquier elemento puede invalidar el valor que obtiene de su elemento primario.

Sugerencia

Si necesitas cambiar la dirección del flujo, establece la propiedad FlowDirection en una ventana, página o diseño raíz. Esto hace que todos los elementos contenidos dentro de la aplicación, la página o el diseño raíz, respondan adecuadamente a la dirección del flujo.

Configuración de la plataforma

Se requiere una configuración de la plataforma específica para habilitar las configuraciones regionales de derecha a izquierda.

Android

Las aplicaciones creadas con la plantilla de proyecto de aplicación .NET MAUI incluyen automáticamente compatibilidad con configuraciones regionales de derecha a izquierda. Esta compatibilidad está habilitada por el atributo android:supportsRtl que se establece como true en el nodo <application> del archivo AndroidManifest.xml de la aplicación:

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android">
    <application ... android:supportsRtl="true" />
    ...
</manifest>

A continuación, se puede probar la localización de derecha a izquierda cambiando el idioma y la región del dispositivo o el Emulator al idioma de derecha a izquierda. Como alternativa, si has activado las opciones de desarrollador en la aplicación de configuración, puedes habilitar Force RTL layout direction en Settings > Developer Options. Para obtener información sobre cómo configurar las opciones del desarrollador, consulta Configure on-device developer options en developer.android.com.

iOS y Mac Catalyst

La configuración regional de derecha a izquierda necesaria debe agregarse como un idioma compatible con los elementos de matriz para la clave CFBundleLocalizationsInfo.plist. En el ejemplo siguiente se muestra el idioma árabe agregado a la matriz para la clave CFBundleLocalizations:

<key>CFBundleLocalizations</key>
<array>
    <string>en</string>
    <string>ar</string>
</array>

A continuación, se puede probar la localización de derecha a izquierda cambiando el idioma y la región del dispositivo o el simulador a una configuración regional de derecha a izquierda que se haya especificado en Info.plist.

Windows

Se deben especificar los recursos de idioma necesarios en el nodo <Resources> del archivo Package.appxmanifest. Reemplaza <Resource Language="x-generate"> por los elementos <Resource /> de cada uno de los idiomas admitidos. Por ejemplo, el marcado siguiente especifica que los recursos localizados "en" y "ar" están disponibles:

<Resources>
    <Resource Language="en" />
    <Resource Language="ar" />
</Resources>

A continuación, se puede probar la localización de derecha a izquierda cambiando el idioma y la región del dispositivo a la configuración regional de derecha a izquierda adecuada.

Prueba de la localización

En tiempo de ejecución, la aplicación carga los recursos localizados apropiados para cada subproceso, en función de la referencia cultural especificada por la propiedad CurrentUICulture.

La mejor manera de probar la localización consiste en cambiar el idioma del dispositivo en la aplicación de configuración en cada dispositivo.

Advertencia

Es posible establecer el valor de CurrentUICulture en el código, pero el comportamiento es incoherente entre las plataformas, por lo que no se recomienda para las pruebas.