WinForms应用程序的正确本地化

40

我有一个 WinForms 应用程序,想要将其翻译成多种语言。然而,我没有任何本地化 WinForms 应用程序的经验,并且对此主题有很多矛盾的信息。

基本上,我想要的是:

  • 在源代码中,每种语言只需要一个文件。
  • 编译时,该文件会被编译进主应用程序 - 不需要构建应用程序后再添加卫星程序集或外部数据文件。
  • 用户可以选择语言,我不需要/不想要基于操作系统的自动检测。
  • 这应该主要包含 stringsints,但也包括 CultureInfo

我看到的大多数解决方案都要么是每个 Form 一个.resx 文件,要么是外部卫星程序集。

  • 我必须自己开发吗?
  • 或者框架中已经有这样的东西了吗?

.net Framework 3.5 SP1如果有关系的话。

编辑:

就大多数情况而言,Visual Studio 已经提供了我想要的支持,但是有两个问题。当我将 Form.Localizable 设置为 true 时,我有这个很好的 Designer 支持,但是这会生成每个 Form 一个.resx 文件。手动在 InitializeComponent 中覆盖它的想法会失败,因为它是由设计器编写的代码,会经常被覆盖。

理论上,我只想要:

  • a) 覆盖创建 ComponentResourceManager 的操作,使其指向我的全局 resx;和
  • b) 将对 ApplyResources 的调用更改为接受第三个参数为 CultureInfo 的重载函数。

看起来我需要在构造函数中添加一个函数调用,该函数在InitializeComponent()之后被调用并覆盖其行为。这似乎非常低效,但当Visual Studio警告不要修改InitializeComponent()时是正确的。

目前,我正在开发自己的WinForms本地化框架...


1
不太确定您是要求“正式”的本地化方式还是“非常定制”的本地化方式。 - H H
1
“一个表单一个.resx文件,每种语言和程序集一个卫星程序集”的方法有什么问题吗? 这确实是.NET的工作方式-如果您不喜欢这种方式,恐怕您必须自己编写很多代码。” - marc_s
2
错误意味着“每个表单一个.resx”(+至少一个用于所有不属于表单的内容)呈指数级增长,而每种语言一个程序集只是额外的混乱,如果新/更正的本地化仅允许在应用程序的新版本中进行。另请参见http://redsolo.blogspot.com/2006/11/localisation-gone-wrong-in-c.html。 - Michael Stum
2
好的,这是标准的.NET处理方式,因此,框架中对这些事情有支持。如果你想要完全不同的东西,那就只能自己解决了,需要编写大量的“管道”软件才能获得.NET框架已经提供的功能。我认为这是一个相当大的挑战,如果你想花费所有时间和精力来以“其他方式”完成它,我会认真重新考虑。 - marc_s
4
@MichaelStum - 技术上说,它是以几何级数增长而不是指数级别增长。 :) 语言的数量是一个乘数,而不是指数。 :) :) 每种语言每种表单都有一个resx的原因在于,对于特定的语言,表单的大小可能需要更改,控件的位置可能需要更改,图标可能需要更改,基本上表单的任何内容可能需要按照每种语言的要求进行更改。因此,RESX文件必须相应增加。该表单中的字符串与该表单的其他所有特定内容都位于同一文件中。 - Jesse Chisholm
6个回答

19
我刚完成了一个C# .Net 3.5项目,遇到了类似的问题。我们正在为一个包含8种语言(包括英语)的现有多语言应用编写WinForms插件。
下面是我们采取的做法:
1. 在默认语言英语中创建所有表单和用户界面。 2. 将所有内部字符串放入资源文件中(与表单没有直接关联的内容,如自定义错误消息和对话框标题等)。
完成大部分工作和测试后,我们进行本地化。
1. 每个表单已经有一个.resx文件,但是这个文件是空的。我们将“Localizable”属性设置为true,并用按钮大小和字符串等来填充.resx文件。 2. 对于其他每种语言,我们更改了表单上的“Language”属性。我们选择了每种语言的基本版本,例如:“西班牙语”而不是“西班牙语(智利)”,以便它适用于每种“西班牙语”方言。 3. 然后,我们浏览每个控件,翻译其文本并调整大小(如果需要)。这会创建每种语言和表单组合的.resx。
最终,对于8种语言,我们得到了每个表单和每个通用字符串的8个.resx。编译后输出文件夹中包含我们正在创建的.dll和每种语言的子文件夹,其中包含.resources.dll。
我们可以通过更改语言属性来测试设计师中的UI版本,以检查是否有正确的字符串和布局。
总的来说,一旦我们理解了它,就非常容易和无痛苦。我们不需要编写任何自定义调整表单加载的代码。

6
抱歉,我不能推荐这种技术。当表单需要添加、移除或调整字段时,它会变成一个维护上的噩梦。 - RenniePet
6
遗憾的是,大多数情况下这确实是MSDN建议WinForms本地化的方法。 :( https://msdn.microsoft.com/en-us/library/y99d1cd3(VS.80).aspx - Jesse Chisholm
1
这是微软推荐的方法,但它很糟糕。 - Derek Tomes
1
在第一步骤中,您可以通过检查您的中性语言设置来确定默认(回退)语言。在WinForms应用程序中,“中性语言”的默认值为“(None)”。在本地化应用程序时,您应该将“(None)”更改为列表框中提供的众多语言之一(例如,“英语(美国)”)。 - DavidRR
2
@RenniePet 我不明白。如果您在表单上删除一个字段,它对应的资源也会被删除。重命名也是一样的。我正在使用这种技术来支持三种语言的应用程序(其中一种只是中性语言,不会被使用)。唯一繁琐的部分是每次需要“选择”要更改本地化的表单和语言,但我认为它很有效。 - MarioDS
@RenniePet,你推荐什么技术呢?从MarioDS的信息来看,这似乎是一种非常糟糕的方式。 - greenoldman

4

我无法解决您的第一个和第二个需求,但请记住,本地化表单并不像简单地翻译每个单词那样简单。您需要检查每个翻译文本是否适合其相应的控件。此外,也许您有一个图标或图像需要在另一个文化中进行更改。

对于您的第三点,您可以使用以下代码手动更改语言:

CultureInfo ci = new CultureInfo("fr");
Thread.CurrentThread.CurrentUICulture = ci; 

4

我之前问了关于ASP.NET的类似问题,并得到了第一个答案 - 这个工具及其工作流可能也适合您 - 可以看一下:Lingobit Localizer

它似乎可以加载您的Winforms应用程序,并允许您开始翻译标签等,同时查看表单。还有很多其他功能,例如增量翻译和翻译记忆(如果您反复使用相同术语)。

对于Winforms来说,看起来非常有前途 - 不过我自己没有使用过。

这里是一个潜在的.NET本地化工具的广泛列表 - 不确定它们的工作效果和涵盖范围如何 - 可以看一下,也许您会找到您需要的内容。

Marc


这个软件创建卫星,但OP说他不想要任何卫星文件。 - Francis B.
1
是的,我知道 - 我试图表明,也许借助适当的工具支持,卫星程序集方法并不那么糟糕。 - marc_s

3
这是一个庞大的主题,有许多方法可以实现您想要的目标。框架提供了基础,但完整的解决方案需要您自己实现某些元素。
例如,默认框架实现是为每个资源创建一个 .resx 文件。在 ASP.Net 中,这意味着每个用户/服务器控件或页面。这不利于易于维护,如果您想将资源移动到数据库中,则需要实现自己的提供程序。
我对 Winforms 的熟悉有限,但如果您正在使用 Silverlight 或 WPF,则可以阅读 Guy Smith-Ferrier 在以下主题上的工作:http://www.guysmithferrier.com/category/Internationalization.aspx。他还有一些工具集可以使您的生活更轻松:http://www.dotneti18n.com/Downloads.aspx
我以前与他合作过,从未遇到过任何其他人对该主题有更深入的理解。

1
您所需要的内容:
1.没有卫星资源文件。 2.每个表单只有一个大小和控件位置。 3.可嵌入执行文件的多种语言。
这在普通的Visual Studio IDE中是做不到的。需要一些定制工作,基本上需要完成以下步骤:
1.获取自定义的资源管理器,处理TMX资源文件。 2.将所有本地化字符串放入TMX文件中。 3.将此TMX文件作为项目中的“嵌入式”资源。 4.在Form构造函数中,创建您的TMX ResourceManager,从嵌入的资源中加载TMX文件。 5.在代码中,使用您的tmx ResourceManager获取本地化字符串,而不是默认的ResourceManager。 6.让表单使用默认的ResourceManager获取除字符串以外的所有设计器内容。 7.使用新语言翻译完整的TMX文件。 8.在下一个版本发布之前,可以通过将它们添加到此TMX文件中来添加更多内容。

资源:(远非详尽列表)


1

正确的方法是,假设您想添加支持阿拉伯语从右到左的语言:

  1. 双击表单
  2. 将localizable属性设置为true
  3. 更改Language属性为阿拉伯语 // 这将自动打开一个新版本的表单,以便您进行自定义。
  4. 将RightToLeft属性设置为Yes
  5. 将RightToLeftLayout属性设置为True
  6. 开始重命名控件,并保存表单。
  7. 在代码中处理消息/错误 // 很抱歉我现在没有快速解决方案,尝试复制它们并If/Else当前本地化。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接