如何在C#中使用本地化

时间:2009-07-17 11:53:14

标签: c# localization cultureinfo

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

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

我该怎么做?

9 个答案:

答案 0 :(得分:537)

  • 通过执行以下操作,将资源文件添加到项目中(您可以将其命名为“strings.resx”):
    右键单击项目中的属性,选择添加 - >上下文菜单中的New Item ... ,然后在 Visual C#Items 列表中选择“资源文件”,并将其命名为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。

答案 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属性更改为您想要的语言(从一个漂亮的下拉菜单中全部输入)
  • 翻译该表单中的控件并在需要时移动它们(压缩那些非常长的法语句子!)

MSDN article on Localizing Windows Forms提供了更多信息。

答案 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文件标签中)
  • 在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.resxstrings.fr-CA.resx

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

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

请注意,特定于语言的资源会生成satellite assemblies

另请了解CurrentCultureCurrentUICulture 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解决方案

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

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

您现在唯一要做的是:

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

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

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

更多信息:

答案 6 :(得分:0)

除了 @Eric Bole-Feysot 回答:

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

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

有一个名为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) );
    }
}

¹(我是该库的维护者)

相关问题