如何在 C# 中使用本地化
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/1142802/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
How to use localization in C#
提问by JL.
I just can't seem to get localization to work.
我似乎无法让本地化工作。
I have a class library. Now I want to create resxfiles in there, and return some values based on the thread culture.
我有一个类库。现在我想在那里创建resx文件,并根据线程文化返回一些值。
How can I do that?
我怎样才能做到这一点?
采纳答案by Fredrik M?rk
- Add a Resource file to your project (you can call it "strings.resx") by doing the following:
Right-click Propertiesin the project, select Add -> New Item...in the context menu, then in the list of Visual C# Itemspick "Resources file"and name itstrings.resx
. - Add a string resouce in the resx file and give it a good name (example: name it "Hello" with and give it the value "Hello")
- Save the resource file (note:this will be the defaultresource file, since it does not have a two-letter language code)
- Add references to your program:
System.Threading
andSystem.Globalization
- 通过执行以下操作将资源文件添加到您的项目(您可以将其称为“strings.resx”):
右键单击项目中的Properties,在上下文菜单中选择Add -> New Item...,然后在Visual C# 项目选择“资源文件”并将其命名为strings.resx
. - 在 resx 文件中添加一个字符串资源并为其命名(例如:将其命名为“Hello”并为其赋予值“Hello”)
- 保存资源文件(注意:这将是默认资源文件,因为它没有两个字母的语言代码)
- 添加对您的程序的引用:
System.Threading
和System.Globalization
Run this code:
运行此代码:
Console.WriteLine(Properties.strings.Hello);
It should print "Hello".
它应该打印“你好”。
Now, add a new resource file, named "strings.fr.resx" (note the "fr" part; this one will contain resources in French). Add a string resource with the same name as in strings.resx, but with the value in French (Name="Hello", Value="Salut"). Now, if you run the following code, it should print Salut:
现在,添加一个名为“strings.fr.resx”的新资源文件(注意“fr”部分;这个将包含法语资源)。添加一个与strings.resx 同名的字符串资源,但值为法语(Name="Hello", Value="Salut")。现在,如果您运行以下代码,它应该打印 Salut:
Thread.CurrentThread.CurrentUICulture = CultureInfo.GetCultureInfo("fr-FR");
Console.WriteLine(Properties.strings.Hello);
What happens is that the system will look for a resource for "fr-FR". It will not find one (since we specified "fr" in your file"). It will then fall back to checking for "fr", which it finds (and uses).
发生的情况是系统将为“fr-FR”寻找资源。它不会找到一个(因为我们在您的文件中指定了“fr”)。然后它会回退到检查它找到(并使用)的“fr”。
The following code, will print "Hello":
以下代码将打印“Hello”:
Thread.CurrentThread.CurrentUICulture = CultureInfo.GetCultureInfo("en-US");
Console.WriteLine(Properties.strings.Hello);
That is because it does not find any "en-US" resource, and also no "en" resource, so it will fall back to the default, which is the one that we added from the start.
那是因为它没有找到任何“en-US”资源,也没有“en”资源,所以它会回退到默认值,这是我们从一开始就添加的。
You can create files with more specific resources if needed (for instance strings.fr-FR.resx and strings.fr-CA.resx for French in France and Canada respectively). In each such file you will need to add the resources for those strings that differ from the resource that it would fall back to. So if a text is the same in France and Canada, you can put it in strings.fr.resx, while strings that are different in Canadian french could go into strings.fr-CA.resx.
如果需要,您可以创建具有更多特定资源的文件(例如,分别用于法国和加拿大法语的 strings.fr-FR.resx 和 strings.fr-CA.resx)。在每个这样的文件中,您将需要为那些与将回退到的资源不同的字符串添加资源。所以如果一个文本在法国和加拿大是一样的,你可以把它放在strings.fr.resx 中,而在加拿大法语中不同的字符串可以放在strings.fr-CA.resx 中。
回答by OregonGhost
It's quite simple, actually. Create a new resource file, for example Strings.resx
. Set Access Modifier
to Public
. Use the apprioriate file template, so Visual Studio will automatically generate an accessor class (the name will be Strings
, in this case). This is your default language.
其实很简单。创建一个新的资源文件,例如Strings.resx
. 设置Access Modifier
为Public
。使用适当的文件模板,因此 Visual Studio 将自动生成一个访问器类(Strings
在这种情况下,名称将为)。这是您的默认语言。
Now, when you want to add, say, German localization, add a localized resx file. This will be typically Strings.de.resx
in this case. If you want to add additional localization for, say, Austria, you'll additionally create a Strings.de-AT.resx
.
现在,当你想添加,比如德语本地化时,添加一个本地化的 resx 文件。Strings.de.resx
在这种情况下通常是这样。如果你想为奥地利添加额外的本地化,你将额外创建一个Strings.de-AT.resx
.
Now go create a string - let's say a string with the name HelloWorld
. In your Strings.resx
, add this string with the value "Hello, world!". In Strings.de.resx
, add "Hallo, Welt!". And in Strings.de-AT.resx
, add "Servus, Welt!". That's it so far.
现在去创建一个字符串 - 假设一个名为 的字符串HelloWorld
。在您的 中Strings.resx
,添加值为“Hello, world!”的字符串。在 中Strings.de.resx
,添加“您好,世界!”。在 中Strings.de-AT.resx
,添加“Servus,Welt!”。到此为止。
Now you have this generated Strings
class, and it has a property with a getter HelloWorld
. Getting this property will load "Servus, Welt!" when your locale is de-AT, "Hallo, Welt! when your locale is any other de locale (including de-DE and de-CH), and "Hello, World!" when your locale is anything else. If a string is missing in the localized version, the resource manager will automatically walk up the chain, from the most specialized to the invariant resource.
现在你有了这个生成的Strings
类,它有一个带有 getter 的属性HelloWorld
。获取此属性将加载“Servus,Welt!” 当您的语言环境是 de-AT 时,“Hallo, Welt!当您的语言环境是任何其他 de-DE 和 de-CH”时,以及“Hello, World!” 当您的语言环境是其他任何东西时。如果一个字符串是在本地化版本中缺少,资源管理器将自动沿着链向上走,从最专业的资源到不变的资源。
You can use the ResourceManager
class for more control about how exactly you are loading things. The generated Strings
class uses it as well.
您可以使用ResourceManager
该类来更好地控制加载内容的准确程度。生成的Strings
类也使用它。
回答by Eric Bole-Feysot
Great answer by F.M?rk. But if you want to update translation, or add new languages once the application is released, you're stuck, because you always have to recompile it to generate the resources.dll.
FM?rk 的出色回答。但是,如果您想在应用程序发布后更新翻译或添加新语言,您就会陷入困境,因为您总是必须重新编译它以生成 resources.dll。
Here is a solution to manually compile a resource dll. It uses the resgen.exe and al.exe tools (installed with the sdk).
这是手动编译资源dll的解决方案。它使用 resgen.exe 和 al.exe 工具(随 sdk 安装)。
Say you have a Strings.fr.resx resource file, you can compile a resources dll with the following batch:
假设您有一个 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
Be sure to keep the original namespace in the file names (here "WpfRibbonApplication1")
确保在文件名中保留原始命名空间(此处为“WpfRibbonApplication1”)
回答by noelicus
In addition @Fredrik M?rk's great answer on strings, to add localization to a formdo the following:
此外@Fredrik M?rk 对字符串的出色回答,要将本地化添加到表单中,请执行以下操作:
- Set the form's property
"Localizable"
totrue
- Change the form's
Language
property to the language you want (from a nice drop-down with them all in) - Translate the controls in that form and move them about if need be (squash those really long full French sentences in!)
- 将表单的属性设置
"Localizable"
为true
- 将表单的
Language
属性更改为您想要的语言(从包含所有内容的漂亮下拉菜单中) - 翻译该表单中的控件并在需要时移动它们(将那些非常长的完整法语句子压入!)
Edit: This MSDN article on Localizing Windows Formsis not the original one I linked ... but might shed more light if needed. (the old one has been taken away)
编辑:这篇关于本地化 Windows 窗体的 MSDN 文章不是我链接的原始文章......但如果需要,可能会提供更多信息。(旧的已经拿走了)
回答by Tomasz Malik
In addition to @Eric Bole-Feysotanswer:
除了@Eric Bole-Feysot 的回答:
Thanks to satellite assemblies, localization can be created based on .dll/.exefiles. This way:
借助附属程序集,可以基于.dll/.exe文件创建本地化。这边走:
- source code (VS project) could be separated from language project,
- adding a new language does not require recompiling the project,
- translation could be made even by the end-user.
- 源代码(VS 项目)可以与语言项目分离,
- 添加新语言不需要重新编译项目,
- 甚至最终用户也可以进行翻译。
There is a little known tool called LSACreator(free for non-commercial use or buy option) which allows you to create localization based on .dll/.exe files. In fact, internally (in language project's directory) it creates/manages localized versions of resx files and compiles an assembly in similar way as @Eric Bole-Feysotdescribed.
有一个鲜为人知的工具叫做LSACreator(免费用于非商业用途或购买选项),它允许您基于 .dll/.exe 文件创建本地化。事实上,在内部(在语言项目的目录中)它创建/管理 resx 文件的本地化版本,并以与@Eric Bole-Feysot描述的类似的方式编译程序集。
回答by Aleksandr
In my case
就我而言
[assembly: System.Resources.NeutralResourcesLanguage("ru-RU")]
in the AssemblyInfo.cs prevented things to work as usual.
在 AssemblyInfo.cs 中阻止了事情像往常一样工作。
回答by Andrey Moiseev
A fix and elaboration of @Fredrik M?rkanswer.
@Fredrik M?rk答案的修复和详细说明。
- Add a
strings.resx
Resource file to your project (or a different filename) - Set
Access Modifier
toPublic
(in the openedstrings.resx
file tab) - Add a string resouce in the resx file: (example: name
Hello
, valueHello
) - Save the resource file
- 将
strings.resx
资源文件添加到您的项目(或不同的文件名) - 设置
Access Modifier
为Public
(在打开的strings.resx
文件选项卡中) - 在 resx 文件中添加字符串资源:(例如: name
Hello
, valueHello
) - 保存资源文件
Visual Studio auto-generates a respective strings
class, which is actually placed in strings.Designer.cs
. The class is in the same namespace that you would expect a newly created .cs
file to be placed in.
Visual Studio 自动生成相应的strings
类,该类实际上放置在strings.Designer.cs
. 该类位于您希望.cs
放置新创建的文件的同一命名空间中。
This code always prints Hello
, because this is the default resource and no language-specific resources are available:
此代码始终打印Hello
,因为这是默认资源并且没有可用的语言特定资源:
Console.WriteLine(strings.Hello);
Now add a new language-specific resource:
现在添加一个新的特定于语言的资源:
- Add
strings.fr.resx
(for French) - Add a string with the same name as previously, but different value: (name
Hello
, valueSalut
)
- 添加
strings.fr.resx
(法语) - 添加一个与之前同名但值不同的字符串:(name
Hello
, valueSalut
)
The following code prints Salut
:
以下代码打印Salut
:
Thread.CurrentThread.CurrentUICulture = CultureInfo.GetCultureInfo("fr-FR");
Console.WriteLine(strings.Hello);
What resource is used depends on Thread.CurrentThread.CurrentUICulture
. It is set depending on Windows UI language setting, or can be set manually like in this example. Learn more about this here.
使用什么资源取决于Thread.CurrentThread.CurrentUICulture
. 它根据 Windows UI 语言设置进行设置,或者可以像本示例中那样手动设置。在此处了解更多信息。
You can add country-specific resources like strings.fr-FR.resx
or strings.fr-CA.resx
.
您可以添加特定于国家/地区的资源,例如strings.fr-FR.resx
或strings.fr-CA.resx
。
The string to be used is determined in this priority order:
要使用的字符串按以下优先级顺序确定:
- From country-specific resource like
strings.fr-CA.resx
- From language-specific resource like
strings.fr.resx
- From default
strings.resx
- 来自特定国家的资源,如
strings.fr-CA.resx
- 来自特定于语言的资源,如
strings.fr.resx
- 从默认
strings.resx
Note that language-specific resources generate satellite assemblies.
请注意,特定于语言的资源会生成附属程序集。
Also learn how CurrentCulture
differs from CurrentUICulture
here.
还可以了解CurrentCulture
与CurrentUICulture
此处的不同之处。
回答by Tag
ResourceManager and .resx are bit messy.
ResourceManager 和 .resx 有点乱。
You could use Lexical.Localization1 which allows embedding default value and culture specific values into the code, and be expanded in external localization files for futher cultures (like .json or .resx).
您可以使用Lexical.Localization1,它允许将默认值和特定于文化的值嵌入到代码中,并在外部本地化文件中扩展以获取更多文化(如 .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) );
}
}
1 (I'm maintainer of that library)
1(我是那个库的维护者)
回答by juFo
In general you put your translations in resource files, e.g. resources.resx.
通常,您将翻译放在资源文件中,例如 resources.resx。
Each specific culture has a different name, e.g. resources.nl.resx, resources.fr.resx, resources.de.resx, …
每个特定的文化都有不同的名称,例如 resources.nl.resx、resources.fr.resx、resources.de.resx、...
Now the most important part of a solution is to maintain your translations. In Visual Studio install the Microsoft MAT tool: Multilingual App Toolkit (MAT). Works with winforms, wpf, asp.net (core), uwp, …
现在,解决方案最重要的部分是维护您的翻译。在 Visual Studio 中安装 Microsoft MAT 工具:多语言应用工具包 (MAT)。适用于 winforms、wpf、asp.net(核心)、uwp……
In general, e.g. for a WPF solution, in the WPF project
通常,例如对于 WPF 解决方案,在 WPF 项目中
- Install the Microsoft MAT extension for Visual Studio.
- In the Solution Explorer, navigate to your Project > Properties > AssemblyInfo.cs
- Add in AssemblyInfo.cs your default, neutral language (in my case English):
[assembly: System.Resources.NeutralResourcesLanguage("en")]
- Select your project in Solution Explorer and in Visual Studio, from the top menu, click "Tools" > "Multilingual App Toolkit" > "Enable Selection", to enable MAT for the project.
- Now Right mouse click on the project in Solution Explorer, select "Multilingual App Toolkit" > "Add translation languages…" and select the language that you want to add translations for. e.g. Dutch.
- 为 Visual Studio 安装 Microsoft MAT 扩展。
- 在解决方案资源管理器中,导航到您的项目 > 属性 > AssemblyInfo.cs
- 在 AssemblyInfo.cs 中添加您的默认中性语言(在我的情况下是英语):
[assembly: System.Resources.NeutralResourcesLanguage("en")]
- 在解决方案资源管理器和 Visual Studio 中选择您的项目,从顶部菜单中,单击“工具”>“多语言应用程序工具包”>“启用选择”,为项目启用 MAT。
- 现在右键单击解决方案资源管理器中的项目,选择“多语言应用程序工具包”>“添加翻译语言...”,然后选择要为其添加翻译的语言。例如荷兰语。
What you will see is that a new folder will be created, called "MultilingualResources" containing a ....nl.xlf
file.
您将看到将创建一个名为“MultilingualResources”的新文件夹,其中包含一个....nl.xlf
文件。
The only thing you now have to do is:
你现在唯一要做的就是:
- add your translation to your default resources.resx file (in my case English)
- Translate by clicking the .xlf file (NOT the .resx file) as the .xlf files will generate/update the .resx files.
- 将您的翻译添加到您的默认 resources.resx 文件(在我的情况下是英语)
- 通过单击 .xlf 文件(不是 .resx 文件)进行翻译,因为 .xlf 文件将生成/更新 .resx 文件。
(the .xlf files should open with the "Multilingual Editor", if this is not the case, right mouse click on the .xlf file, select "Open With…" and select "Multilingual Editor".
(.xlf 文件应使用“多语言编辑器”打开,如果不是这种情况,请在 .xlf 文件上单击鼠标右键,选择“打开方式...”并选择“多语言编辑器”。
Have fun! now you can also see what has not been translated, export translations in xlf to external translation companies, import them again, recycle translations from other projects etc...
玩得开心!现在您还可以查看未翻译的内容、将 xlf 中的翻译导出到外部翻译公司、再次导入、回收其他项目的翻译等...
More info:
更多信息:
- Using the Multilingual App Toolkit 4.0: https://docs.microsoft.com/windows/uwp/design/globalizing/use-mat
- Multilingual App Toolkit blog, visit: http://aka.ms/matblog
- Multilingual App Toolkit User Voice feature voting site, visit: http://aka.ms/matvoice
- 使用多语言应用工具包 4.0:https: //docs.microsoft.com/windows/uwp/design/globalizing/use-mat
- 多语言应用工具包博客,请访问:http: //aka.ms/matblog
- 多语言应用工具包用户语音功能投票网站,请访问:http: //aka.ms/matvoice