287

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

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

我怎样才能做到这一点?

4

9 回答 9

615
  • 通过执行以下操作将资源文件添加到您的项目(您可以将其称为“strings.resx”):
    右键单击项目中的Properties ,在上下文菜单中选择Add -> New Item...,然后在列表中Visual C# 项目选择“资源文件”并将其命名为strings.resx.
  • 在 resx 文件中添加一个字符串 resouce 并为其命名(例如:将其命名为“Hello”,并为其命名为“Hello”)
  • 保存资源文件(注意:这将是默认资源文件,因为它没有两个字母的语言代码)
  • 添加对您的程序的引用:System.ThreadingSystem.Globalization

运行此代码:

Console.WriteLine(Properties.strings.Hello);

它应该打印“你好”。

现在,添加一个名为“strings.fr.resx”的新资源文件(注意“fr”部分;这将包含法语资源)。添加与 strings.resx 中名称相同的字符串资源,但其值为法语(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中。

于 2009-07-17T12:01:47.633 回答
46

其实很简单。创建一个新的资源文件,例如Strings.resx. 设置Access ModifierPublic。使用适当的文件模板,因此 Visual Studio 将自动生成一个访问器类(在这种情况下,名称将是Strings)。这是您的默认语言。

现在,当您想添加德语本地化时,请添加本地化的 resx 文件。这通常是Strings.de.resx在这种情况下。如果您想为奥地利添加额外的本地化,您将另外创建一个Strings.de-AT.resx.

现在去创建一个字符串 - 假设是一个名为 的字符串HelloWorld。在您的Strings.resx中,添加值为“Hello, world!”的字符串。在Strings.de.resx中,添加“你好,世界!”。并在Strings.de-AT.resx中添加“Servus,Welt!”。到目前为止就是这样。

现在你有了这个生成Strings的类,它有一个带有 getter 的属性HelloWorld。获取此属性将加载“Servus, Welt!” 当您的语言环境是 de-AT 时,“Hallo, Welt! 当您的语言环境是任何其他 de 语言环境(包括 de-DE 和 de-CH)时,以及“Hello, World!” 当您的语言环境是其他任何东西时。如果一个字符串是在本地化版本中缺少,资源管理器将自动从最专业的资源到不变的资源。

您可以使用ResourceManager该类来更好地控制您正在加载的内容。生成的Strings类也使用它。

于 2009-07-17T12:02:24.467 回答
19

除了@Fredrik Mörk 对字符串的出色回答,要向表单添加本地化,​​请执行以下操作:

  • 表单的属性设置"Localizable"true
  • 将表单的Language属性更改为您想要的语言(从一个很好的下拉列表中)
  • 翻译该形式的控件并在需要时移动它们(将那些非常长的完整法语句子压扁!)

编辑:这篇关于本地化 Windows 窗体的 MSDN 文章不是我链接的原始文章……但如果需要,可能会提供更多信息。(旧的已经被拿走了)

于 2012-09-20T10:51:54.027 回答
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”)

于 2012-07-18T09:24:22.603 回答
12

@Fredrik Mörk答案的修复和详细说明。

  • strings.resx资源文件添加到您的项目(或不同的文件名)
  • 设置Access ModifierPublic(在打开的strings.resx文件选项卡中)
  • 在 resx 文件中添加一个字符串资源:(例如:名称Hello、值Hello
  • 保存资源文件

Visual Studio 会自动生成一个相应的strings类,该类实际上放在strings.Designer.cs. 该类与您希望将新创建的.cs文件放置在同一个命名空间中。

此代码始终打印Hello,因为这是默认资源并且没有可用的特定于语言的资源:

Console.WriteLine(strings.Hello);

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

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

以下代码打印Salut

Thread.CurrentThread.CurrentUICulture = CultureInfo.GetCultureInfo("fr-FR");
Console.WriteLine(strings.Hello);

使用什么资源取决于Thread.CurrentThread.CurrentUICulture. 它根据 Windows UI 语言设置进行设置,或者可以像本示例中那样手动设置。在此处了解更多信息。

您可以添加特定国家/地区的资源,例如strings.fr-FR.resxstrings.fr-CA.resx

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

  • 来自特定国家/地区的资源,例如strings.fr-CA.resx
  • 来自特定于语言的资源,例如strings.fr.resx
  • 从默认strings.resx

请注意,特定于语言的资源会生成附属程序集

还可以了解CurrentCultureCurrentUICulture 此处的不同之处。

于 2016-11-28T19:24:10.787 回答
2

就我而言

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

在 AssemblyInfo.cs 中阻止了事情像往常一样工作。

于 2015-05-13T07:16:00.163 回答
2

通常,您将翻译放在资源文件中,例如resources.resx。

每种特定的文化都有不同的名称,例如 resources.nl.resx、resources.fr.resx、resources.de.resx……</p>

现在,解决方案最重要的部分是维护您的翻译。在 Visual Studio 中安装 Microsoft MAT 工具:多语言应用工具包 (MAT)。适用于 winforms、wpf、asp.net(核心)、uwp、……</p>

通常,例如对于 WPF 解决方案,在 WPF 项目中

  • 为 Visual Studio 安装 Microsoft MAT 扩展。
  • 在解决方案资源管理器中,导航到您的项目 > 属性 > AssemblyInfo.cs
  • 添加 AssemblyInfo.cs 您的默认中性语言(在我的情况下为英语):[assembly: System.Resources.NeutralResourcesLanguage("en")]
  • 在解决方案资源管理器和 Visual Studio 中选择您的项目,从顶部菜单中单击“工具”>“多语言应用程序工具包”>“启用选择”,为项目启用 MAT。
    • 现在右键单击解决方案资源管理器中的项目,选择“多语言应用工具包”>“添加翻译语言...”,然后选择要为其添加翻译的语言。例如荷兰语。

您将看到将创建一个名为“MultilingualResources”的新文件夹,其中包含一个....nl.xlf文件。

你现在唯一需要做的就是:

  1. 将您的翻译添加到您的默认 resources.resx 文件(在我的情况下为英语)
  2. 通过单击 .xlf 文件(不是 .resx 文件)进行翻译,因为 .xlf 文件将生成/更新 .resx 文件。

(.xlf 文件应使用“多语言编辑器”打开,如果不是这种情况,请右键单击 .xlf 文件,选择“打开方式...”并选择“多语言编辑器”。

玩得开心!现在您还可以查看未翻译的内容、将 xlf 中的翻译导出到外部翻译公司、再次导入它们、从其他项目回收翻译等...

更多信息:

于 2020-01-31T08:09:16.097 回答
0

除了@Eric Bole-Feysot回答:

借助附属程序集,可以基于.dll/.exe文件创建本地化。这边走:

  • 源代码(VS项目)可以从语言项目中分离出来,
  • 添加新语言不需要重新编译项目,
  • 甚至最终用户也可以进行翻译。

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

于 2015-02-11T00:17:15.413 回答
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) );
    }
}

¹(我是那个库的维护者)

于 2019-06-08T12:51:56.427 回答