Parece que no puedo conseguir que la localización funcione.
Tengo una biblioteca de clase. Ahora quiero crear archivos resx allí y devolver algunos valores basados en la cultura del hilo.
¿Cómo puedo hacer eso?
Parece que no puedo conseguir que la localización funcione.
Tengo una biblioteca de clase. Ahora quiero crear archivos resx allí y devolver algunos valores basados en la cultura del hilo.
¿Cómo puedo hacer eso?
Respuestas:
strings.resx
.System.Threading
ySystem.Globalization
Ejecute este código:
Console.WriteLine(Properties.strings.Hello);
Debería imprimir "Hola".
Ahora, agregue un nuevo archivo de recursos, llamado "strings.fr.resx" (tenga en cuenta la parte "fr"; este contendrá recursos en francés). Agregue un recurso de cadena con el mismo nombre que en strings.resx, pero con el valor en francés (Name = "Hello", Value = "Salut"). Ahora, si ejecuta el siguiente código, debería imprimir Salut:
Thread.CurrentThread.CurrentUICulture = CultureInfo.GetCultureInfo("fr-FR");
Console.WriteLine(Properties.strings.Hello);
Lo que sucede es que el sistema buscará un recurso para "fr-FR". No encontrará uno (ya que especificamos "fr" en su archivo "). Luego volverá a buscar" fr ", que encuentra (y usa).
El siguiente código imprimirá "Hola":
Thread.CurrentThread.CurrentUICulture = CultureInfo.GetCultureInfo("en-US");
Console.WriteLine(Properties.strings.Hello);
Esto se debe a que no encuentra ningún recurso "en-US" y tampoco un recurso "en", por lo que volverá al valor predeterminado, que es el que agregamos desde el principio.
Puede crear archivos con recursos más específicos si es necesario (por ejemplo, strings.fr-FR.resx y strings.fr-CA.resx para francés en Francia y Canadá, respectivamente). En cada uno de estos archivos deberá agregar los recursos para aquellas cadenas que difieren del recurso al que recurriría. Entonces, si un texto es el mismo en Francia y Canadá, puede ponerlo en strings.fr.resx, mientras que las cadenas que son diferentes en francés canadiense podrían ir a strings.fr-CA.resx.
Access Modifier
debe establecerse Public
para que se genere la clase de recurso. La clase no está necesariamente en el espacio de nombres de Propiedades, es donde coloca el archivo .resx.
Es bastante simple, en realidad. Cree un nuevo archivo de recursos, por ejemplo Strings.resx
. Establecer Access Modifier
a Public
. Use la plantilla de archivo adecuada, de modo que Visual Studio generará automáticamente una clase de acceso (el nombre será Strings
, en este caso). Este es tu idioma predeterminado.
Ahora, cuando desee agregar, digamos, localización alemana, agregue un archivo resx localizado. Esto será típicamente Strings.de.resx
en este caso. Si desea agregar localización adicional para, por ejemplo, Austria, también creará un Strings.de-AT.resx
.
Ahora ve a crear una cadena, digamos una cadena con el nombre HelloWorld
. En su Strings.resx
, agregue esta cadena con el valor "¡Hola, mundo!". En Strings.de.resx
, agregue "Hola, Welt!". Y en Strings.de-AT.resx
, agregue "Servus, Welt!". Eso es todo hasta ahora.
Ahora tiene esta Strings
clase generada , y tiene una propiedad con un captador HelloWorld
. Obtener esta propiedad cargará "Servus, Welt!" cuando su configuración regional es de-AT, "¡Hola, Welt! cuando su configuración regional es cualquier otra configuración regional (incluyendo de-DE y de-CH), y" ¡Hola, Mundo! "cuando su configuración regional es cualquier otra cosa. Si una cadena es falta en la versión localizada, el administrador de recursos subirá automáticamente por la cadena, desde el recurso más especializado hasta el invariante.
Puede usar la ResourceManager
clase para tener más control sobre cómo carga exactamente las cosas. La Strings
clase generada también lo usa.
Además, la gran respuesta de @Fredrik Mörk sobre cadenas, para agregar localización a un formulario, haga lo siguiente:
"Localizable"
entrue
Language
propiedad del formulario al idioma que desee (de un buen menú desplegable con todos ellos)Editar: este artículo de MSDN sobre Localización de formularios de Windows no es el original que vinculé ... pero podría arrojar más luz si es necesario. (el viejo ha sido quitado)
Gran respuesta de F.Mörk. Pero si desea actualizar la traducción o agregar nuevos idiomas una vez que se lanza la aplicación, está atascado, porque siempre tiene que volver a compilarlo para generar resources.dll.
Aquí hay una solución para compilar manualmente un recurso dll. Utiliza las herramientas resgen.exe y al.exe (instaladas con el sdk).
Supongamos que tiene un archivo de recursos Strings.fr.resx, puede compilar un archivo dll de recursos con el siguiente lote:
resgen.exe /compile Strings.fr.resx,WpfRibbonApplication1.Strings.fr.resources
Al.exe /t:lib /embed:WpfRibbonApplication1.Strings.fr.resources /culture:"fr" /out:"WpfRibbonApplication1.resources.dll"
del WpfRibbonApplication1.Strings.fr.resources
pause
Asegúrese de mantener el espacio de nombres original en los nombres de archivo (aquí "WpfRibbonApplication1")
Una solución y elaboración de la respuesta de @Fredrik Mörk .
strings.resx
archivo de recursos a su proyecto (o un nombre de archivo diferente)Access Modifier
en Public
(en la strings.resx
pestaña del archivo abierto )Hello
, valor Hello
)Visual Studio genera automáticamente una strings
clase respectiva , que en realidad se coloca en strings.Designer.cs
. La clase está en el mismo espacio de nombres en el que esperaría .cs
que se coloque un archivo recién creado .
Este código siempre se imprime Hello
, porque este es el recurso predeterminado y no hay recursos específicos del idioma disponibles:
Console.WriteLine(strings.Hello);
Ahora agregue un nuevo recurso específico del idioma:
strings.fr.resx
(para francés)Hello
, valor Salut
)Se imprime el siguiente código Salut
:
Thread.CurrentThread.CurrentUICulture = CultureInfo.GetCultureInfo("fr-FR");
Console.WriteLine(strings.Hello);
De qué recurso se utiliza depende Thread.CurrentThread.CurrentUICulture
. Se establece según la configuración del idioma de la interfaz de usuario de Windows, o se puede configurar manualmente como en este ejemplo. Obtenga más información sobre esto aquí .
Puede agregar recursos específicos de país como strings.fr-FR.resx
o strings.fr-CA.resx
.
La cadena que se utilizará se determina en este orden de prioridad:
strings.fr-CA.resx
strings.fr.resx
strings.resx
Tenga en cuenta que los recursos específicos del idioma generan conjuntos de satélites .
Aprenda también cómo CurrentCulture
difiere de CurrentUICulture
aquí .
Además de la respuesta @Eric Bole-Feysot :
Gracias a los ensambles satelitales, la localización se puede crear en base a archivos .dll / .exe . De esta manera:
Existe una herramienta poco conocida llamada LSACreator (gratuita para uso no comercial u opción de compra) que le permite crear localización basada en archivos .dll / .exe. De hecho, internamente (en el directorio del proyecto de lenguaje) crea / administra versiones localizadas de archivos resx y compila un ensamblaje de manera similar a como lo describe @Eric Bole-Feysot .
ResourceManager y .resx son un poco desordenados.
Puede usar Lexical.Localization ¹, que permite incrustar valores predeterminados y valores específicos de cultura en el código, y expandirse en archivos de localización externos para otras culturas (como .json o .resx).
public class MyClass
{
/// <summary>
/// Localization root for this class.
/// </summary>
static ILine localization = LineRoot.Global.Type<MyClass>();
/// <summary>
/// Localization key "Ok" with a default string, and couple of inlined strings for two cultures.
/// </summary>
static ILine ok = localization.Key("Success")
.Text("Success")
.fi("Onnistui")
.sv("Det funkar");
/// <summary>
/// Localization key "Error" with a default string, and couple of inlined ones for two cultures.
/// </summary>
static ILine error = localization.Key("Error")
.Format("Error (Code=0x{0:X8})")
.fi("Virhe (Koodi=0x{0:X8})")
.sv("Sönder (Kod=0x{0:X8})");
public void DoOk()
{
Console.WriteLine( ok );
}
public void DoError()
{
Console.WriteLine( error.Value(0x100) );
}
}
¹ (Soy el encargado de mantener esa biblioteca)
En general, coloca sus traducciones en archivos de recursos, por ejemplo resources.resx.
Cada cultura específica tiene un nombre diferente, por ejemplo, resources.nl.resx, resources.fr.resx, resources.de.resx, ...
Ahora la parte más importante de una solución es mantener sus traducciones. En Visual Studio, instale la herramienta MAT de Microsoft: Kit de herramientas de aplicación multilingüe (MAT). Funciona con winforms, wpf, asp.net (core), uwp, ...
En general, por ejemplo, para una solución WPF, en el proyecto WPF
[assembly: System.Resources.NeutralResourcesLanguage("en")]
Lo que verá es que se creará una nueva carpeta, llamada "Recursos multilingües" que contiene un ....nl.xlf
archivo.
Lo único que tienes que hacer ahora es:
(los archivos .xlf deben abrirse con el "Editor multilingüe"; si este no es el caso, haga clic con el botón derecho en el archivo .xlf, seleccione "Abrir con ..." y seleccione "Editor multilingüe".
¡Que te diviertas! ahora también puede ver lo que no se ha traducido, exportar traducciones en xlf a empresas de traducción externas, importarlas nuevamente, reciclar traducciones de otros proyectos, etc.
Más información: