如何在C#中使用本地化

问题描述 投票:250回答:8

我似乎无法让本地化工作。

我有一个类库。现在我想在那里创建resx文件,并根据线程文化返回一些值。

我怎样才能做到这一点?

c# localization cultureinfo
8个回答
541
投票
  • 通过执行以下操作,将资源文件添加到项目中(可以将其命名为“strings.resx”): 右键单击项目中的Properties,在上下文菜单中选择Add - > New Item ...,然后在Visual C#Items列表中选择“Resources file”并将其命名为strings.resx
  • 在resx文件中添加一个字符串资源并给它一个好名字(例如:将其命名为“Hello”,并将其赋值为“Hello”)
  • 保存资源文件(注意:这将是默认资源文件,因为它没有双字母语言代码)
  • 添加对您的程序的引用:System.ThreadingSystem.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。


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类也使用它。


15
投票

另外@FredrikMörk对字符串的答案非常好,要在表单中添加本地化,​​请执行以下操作:

  • 将表单的属性"Localizable"设置为true
  • 将表单的Language属性更改为您想要的语言(从一个漂亮的下拉列表中全部输入)
  • 翻译该表格中的控件并在需要时移动它们(压缩那些真正长满的法语句子!)

编辑:这个MSDN article on Localizing Windows Forms不是我链接的原始...但如果需要可能会更多的光。 (旧的已被带走)


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”)


10
投票

@FredrikMörk答案的修复和细化。

  • strings.resx资源文件添加到项目中(或不同的文件名)
  • Access Modifier设置为Public(在打开的strings.resx文件选项卡中)
  • 在resx文件中添加字符串资源:(示例:name qazxsw poi,value qazxsw poi)
  • 保存资源文件

Visual Studio自动生成相应的Hello类,实际上放在Hello中。该类与您期望将新创建的strings文件放在同一名称空间中。

此代码始终打印strings.Designer.cs,因为这是默认资源,并且没有特定于语言的资源:

.cs

现在添加一个新的语言特定资源:

  • 添加Hello(法语)
  • 添加一个与之前名称相同的字符串,但值不同:(名称Console.WriteLine(strings.Hello); ,值strings.fr.resx

以下代码打印Hello

Salut

使用什么资源取决于Salut。它根据Windows UI语言设置进行设置,或者可以像本例中一样手动设置。了解有关此Thread.CurrentThread.CurrentUICulture = CultureInfo.GetCultureInfo("fr-FR"); Console.WriteLine(strings.Hello); 的更多信息。

您可以添加特定国家/地区的资源,例如Thread.CurrentThread.CurrentUICulturehere

要使用的字符串按此优先级顺序确定:

  • 来自strings.fr-FR.resx等国家特定资源
  • 来自特定语言的资源,如strings.fr-CA.resx
  • 从默认strings.fr-CA.resx

请注意,特定于语言的资源会生成strings.fr.resx

还要了解strings.resxsatellite assemblies CurrentCulture的不同之处。


0
投票

除了@Eric Bole-Feysot回答:

由于附属程序集,可以基于.dll / .exe文件创建本地化。这条路:

  • 源代码(VS项目)可以与语言项目分开,
  • 添加新语言不需要重新编译项目,
  • 即使是最终用户也可以进行翻译。

有一个名为CurrentUICulture的小工具(免费用于非商业用途或购买选项),它允许您基于.dll / .exe文件创建本地化。事实上,在内部(在语言项目的目录中),它创建/管理resx文件的本地化版本,并以与@Eric Bole-Feysot描述的方式类似的方式编译程序集。


0
投票

就我而言

here

在AssemblyInfo.cs中,事情无法正常工作。


0
投票

ResourceManager和.resx有点乱。

您可以使用LSACreator¹,它允许在代码中嵌入默认值和特定于文化的值,并在外部本地化文件中进行扩展,以用于进一步的文化(如.json或.resx)。

[assembly: System.Resources.NeutralResourcesLanguage("ru-RU")]

¹(我是那个图书馆的维护者)

© www.soinside.com 2019 - 2024. All rights reserved.