我似乎无法让本地化工作。
我有一个类库。现在我想在那里创建 resx 文件,并根据线程文化返回一些值。
我该怎么做?
答案 0 :(得分:537)
strings.resx
。 System.Threading
和System.Globalization
运行此代码:
Console.WriteLine(Properties.strings.Hello);
应打印“你好”。
现在,添加一个名为“strings.fr.resx”的新资源文件(注意“fr”部分;这个文件将包含法语资源)。添加一个字符串资源,其名称与strings.resx中的名称相同,但值为French(Name =“Hello”,Value =“Salut”)。现在,如果您运行以下代码,它应该打印Salut:
Thread.CurrentThread.CurrentUICulture = CultureInfo.GetCultureInfo("fr-FR");
Console.WriteLine(Properties.strings.Hello);
系统会为“fr-FR”寻找资源。它不会找到一个(因为我们在你的文件中指定了“fr”)。然后它会回到检查它找到(并使用)的“fr”。
以下代码将打印“Hello”:
Thread.CurrentThread.CurrentUICulture = CultureInfo.GetCultureInfo("en-US");
Console.WriteLine(Properties.strings.Hello);
这是因为它没有找到任何“en-US”资源,也没有找到“en”资源,因此它将回退到默认值,即我们从一开始就添加的默认值。
如果需要,您可以创建具有更多特定资源的文件(例如分别为法国和加拿大的strings.fr-FR.resx和strings.fr-CA.resx)。在每个这样的文件中,您将需要为那些与其回退的资源不同的字符串添加资源。因此,如果法国和加拿大的文本相同,您可以将其放在strings.fr.resx中,而加拿大法语中不同的字符串可以放入strings.fr-CA.resx。
答案 1 :(得分:37)
Strings.resx
。将Access Modifier
设为Public
。使用apprioriate文件模板,因此Visual Studio将自动生成一个访问者类(在这种情况下,名称将为Strings
)。这是您的默认语言。
现在,当您想要添加德语本地化时,请添加本地化的resx文件。在这种情况下,这通常是Strings.de.resx
。如果您想为奥地利添加其他本地化,则还需要创建Strings.de-AT.resx
。
现在去创建一个字符串 - 让我们说一个名为HelloWorld
的字符串。在Strings.resx
中,添加值为“Hello,world!”的字符串。在Strings.de.resx
中,添加“Hallo,Welt!”。在Strings.de-AT.resx
中,添加“Servus,Welt!”。到目前为止就是这样。
现在你有了这个生成的Strings
类,它有一个带有getter HelloWorld
的属性。获得此属性将加载“Servus,Welt!”当您的语言环境是de-AT时,“Hallo,Welt!当您的语言环境是任何其他de locale(包括de-DE和de-CH)时,以及”Hello,World!“当您的语言环境是其他任何内容时。如果字符串是在本地化版本中缺失,资源管理器将自动向上走,从最专业的资源到不变的资源。
您可以使用ResourceManager
类来更好地控制加载内容的准确程度。生成的Strings
类也使用它。
答案 2 :(得分:15)
此外@FredrikMörk对字符串的答案非常好,要将本地化添加到表单,请执行以下操作:
"Localizable"
设置为true
Language
属性更改为您想要的语言(从一个漂亮的下拉菜单中全部输入)答案 3 :(得分:14)
F.Mörk的精彩回答。但是如果你想要在应用程序发布后更新翻译或添加新语言,那么你就会陷入困境,因为你总是需要重新编译它来生成resources.dll。
这是手动编译资源dll的解决方案。它使用resgen.exe和al.exe工具(随sdk一起安装)。
假设您有一个Strings.fr.resx资源文件,您可以使用以下批处理编译资源dll:
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
确保将原始命名空间保留在文件名中(此处为“WpfRibbonApplication1”)
答案 4 :(得分:9)
@FredrikMörk答案的修复和详细说明。
strings.resx
资源文件(或其他文件名)Access Modifier
设置为Public
(在已打开的strings.resx
文件标签中)Hello
,值Hello
) Visual Studio自动生成相应的strings
类,实际放置在strings.Designer.cs
中。该类与您期望将新创建的.cs
文件放在同一名称空间中。
此代码始终打印Hello
,因为这是默认资源,并且没有特定于语言的资源:
Console.WriteLine(strings.Hello);
现在添加一个新的语言特定资源:
strings.fr.resx
(法语)Hello
,值Salut
)以下代码打印Salut
:
Thread.CurrentThread.CurrentUICulture = CultureInfo.GetCultureInfo("fr-FR");
Console.WriteLine(strings.Hello);
使用的资源取决于Thread.CurrentThread.CurrentUICulture
。它根据Windows UI语言设置进行设置,或者可以像本例中一样手动设置。详细了解here。
您可以添加国家/地区特定资源,例如strings.fr-FR.resx
或strings.fr-CA.resx
。
要使用的字符串按以下优先顺序确定:
strings.fr-CA.resx
strings.fr.resx
strings.resx
请注意,特定于语言的资源会生成satellite assemblies。
另请了解CurrentCulture
与CurrentUICulture
here的区别。
答案 5 :(得分:1)
通常,您将翻译内容放入资源文件中,例如resources.resx。
每种特定的文化都有不同的名称,例如resources.nl.resx,resources.fr.resx,resources.de.resx,...
现在,解决方案中最重要的部分是维护您的翻译。 在Visual Studio中,安装Microsoft MAT工具:Multilingual App Toolkit(MAT)。 适用于winforms,wpf,asp.net(核心),uwp,...
通常,例如WPF解决方案中的WPF解决方案
[assembly: System.Resources.NeutralResourcesLanguage("en")]
您将看到将创建一个新文件夹,名为“ MultilingualResources”,其中包含一个....nl.xlf
文件。
您现在唯一要做的是:
(。xlf文件应使用“多语言编辑器”打开,如果不是这种情况,请右键单击.xlf文件,选择“打开方式...”,然后选择“多语言编辑器”。
玩得开心!现在您还可以看到尚未翻译的内容,将xlf中的翻译内容导出到外部翻译公司,再次导入它们,回收其他项目中的翻译内容等...
更多信息:
答案 6 :(得分:0)
除了 @Eric Bole-Feysot 回答:
由于附属程序集,可以基于 .dll / .exe 文件创建本地化。这样:
有一个名为LSACreator的小工具(免费用于非商业用途或购买选项),它允许您基于.dll / .exe文件创建本地化。事实上,在内部(在语言项目的目录中),它创建/管理resx文件的本地化版本,并以与 @Eric Bole-Feysot 描述的方式类似的方式编译程序集。
答案 7 :(得分:0)
就我而言
[assembly: System.Resources.NeutralResourcesLanguage("ru-RU")]
在AssemblyInfo.cs中,阻止了一切正常工作。
答案 8 :(得分:0)
ResourceManager和.resx有点混乱。
您可以使用Lexical.Localization¹,它允许将默认值和区域性特定值嵌入到代码中,并可以在外部本地化文件中扩展以进行进一步的区域性(例如.json或.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) );
}
}
¹(我是该库的维护者)