如何在c#中使用本地化

我只是不能让本地化工作。

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

我该怎么做呢?

254313 次浏览
  • 在你的项目中添加一个资源文件(你可以称它为"strings.resx"),方法如下:
    右键单击项目中的属性,在上下文菜单中选择Add ->新项目…,然后在Visual c#项目列表中选择“资源文件”并将其命名为strings.resx
  • 在resx文件中添加一个字符串资源,并给它一个好名字(例如:将其命名为“Hello”with,并给它赋值“Hello”)
  • 保存资源文件(注意:这将是默认的资源文件,因为它没有两个字母的语言代码)
  • 在程序中添加引用:System.ThreadingSystem.Globalization

运行以下代码:

Console.WriteLine(Properties.strings.Hello);

它应该打印“Hello”。

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

其实很简单。创建一个新的资源文件,例如Strings.resx。将Access Modifier设置为Public。使用适当的文件模板,这样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!”当您的locale为de-AT时,“Hallo, Welt!”当你的locale是任何其他de locale(包括de- de和de- ch)时,和“Hello, World!”当你的locale是任何其他地方时。如果本地化版本中缺少一个字符串,资源管理器将自动沿着链向上走,从最专门化的资源到不变的资源。

你可以使用ResourceManager类来更多地控制你如何加载东西。生成的Strings类也使用它。

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

此外,@Fredrik Mörk关于字符串的精彩回答,要添加对表单的本地化,请执行以下操作:

  • 形式的属性"Localizable"设置为true
  • 将表单的Language属性更改为你想要的语言(从一个漂亮的下拉菜单中)
  • 翻译这种形式的控件,并在需要时移动它们(把那些非常长的完整的法语句子塞进去!)

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

除了@Eric Bole-Feysot答案:

由于卫星程序集,本地化可以基于. dll / . exe文件创建。这种方式:

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

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

对我来说

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

在AssemblyInfo.cs中阻止事情正常工作。

@Fredrik莫克答案的修复和细化。

  • 向项目添加strings.resx资源文件(或其他文件名)
  • Access Modifier设置为Public(在打开的strings.resx文件选项卡中)
  • 在resx文件中添加一个字符串资源:(例如:name Hello, value 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 在这里的区别。

你可以使用词汇。本地化¹,它允许将默认值和特定于区域性的值嵌入到代码中,并在外部本地化文件中展开以用于进一步的区域性(如.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) );
}
}

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

每个特定区域性都有不同的名称,例如resources.nl。Resx, resources.fr.resx, resources.de.resx,…

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

一般来说,例如对于WPF解决方案,在WPF项目中

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

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

    你现在要做的唯一一件事是:

    1. 将翻译添加到默认资源中。resx文件(在我的例子中是英文)
    2. 通过点击.xlf文件(不是.resx文件)进行翻译,因为.xlf文件将生成/更新.resx文件。

    (.xlf文件应该用“多语言编辑器”打开,如果不是这样,鼠标右键单击。xlf文件,选择“用…打开”,然后选择“多语言编辑器”。

    玩得开心!现在你还可以看到没有翻译的内容,用XLF导出翻译到外部翻译公司,再次导入,从其他项目回收翻译等等……

    更多信息: