在C#.Net中获取XAML和RESX资源时的主要装配与Satellite装配问题

时间:2011-12-10 05:12:57

标签: c# wpf localization resx

在包含文化中立XAML文件,一些文化中性图标和本地化字符串的本地化程序中,如何组织这些不同的资源类型以便找到它们?无论我尝试什么安排,我发现我的一种资源类型是无法访问的。

我遇到的问题是:

  • MainWindow.xaml文件始终构建到en-US附属程序集中。如果UltimateResourceFallbackLocation设置为MainAssembly,它将永远不会找到Window的BAML,并且我在InitializeComponent()调用中得到一个异常。所以我觉得被迫将UltimateResourceFallbackLocation设置为“Satellite”。

  • Resources.resx文件中包含的文化中性图标资源始终构建到主EXE程序集中,如果UltimateResourceFallbackLocation设置为Satellite,则无法找到它。这似乎与MainWindow.xaml文件的要求完全不兼容。

  • 如果我完全删除UICulture和NeutralResourcesLanguage - 这会强制XAML和RESX数据都构建到MainAssembly中,那么我的特定于文化的字符串不起作用。

问题是:我做错了什么?我应该如何构建项目,以便可以访问这三种类型的资源。

编辑(工作解决方案,但似乎有误):

我设法让我的文化中立的RESX文件Resources.resx通过完全复制它来构建到Satellite程序集中,重命名重复的Resources.en-US.resx并将Resources.resx设置为Build Action:None(所以Resources.resx仅用于生成Resources.Designer.cs文件,但不再将数据插入主EXE程序集中。

该程序现在适用于所有三种情况(本地化字符串,来自resx的非本地化数据和来自XAML的非本地化数据),因为我所有的文化中立资源现在都在en-US程序集中 - 但是重复了资源。 resx文件实现这一点似乎很傻。

傻吗?有更聪明的方法吗?

2 个答案:

答案 0 :(得分:3)

由于文档错误,使用WPF进行本地化非常麻烦。我花了几个小时来获得一些见解。

  

MainWindow.xaml文件始终构建到en-US附属程序集中。如果UltimateResourceFallbackLocation设置为MainAssembly,它将永远不会找到Window的BAML,并且我在InitializeComponent()调用中得到一个异常。所以我觉得被迫将UltimateResourceFallbackLocation设置为“Satellite”。

这是因为您的project.vcproj文件可能包含<UICulture>en-US</UICulture>。这基本上告诉VS生成stellite程序集(你看到正在使用相应的卫星创建文件夹en-US)。

UltimateResourceFallbackLocation.MainAssembly现在告诉.net加速查找本地化信息,使用嵌入式信息而不是匹配目录中的信息。如果您的系统文化是en-US,它将完美地解释这种行为。

quoting Kim Hamilton

  

...然后ResourceManager直接在主程序集中查找“en-US”资源,而不是首先在“en-US”文件夹中搜索。由于资源探测可能很昂贵,因此该属性可以帮助改善性能。

由于您已找到第二个要点的解决方案,因此只剩下一个:

  

如果我完全删除UICulture和NeutralResourcesLanguage - 这会强制XAML和RESX数据都构建到MainAssembly中,那么我的特定于文化的字符串不起作用。

实际上WPF仍然进行本地化:当.vcproj文件中没有像<UICulture>en-US</UICulture>这样的条目时,wpf仍会尝试在名称与System.Threading.Thread.CurrentThread.CurrentUICulture匹配的目录中查找卫星。它被发现,它正在被使用。当然,除非您的中性语言设置为您的系统语言并且您使用主程序集回退策略。为了测试你的en-US系统的本地化,你应该选择一些其他的文化,例如ja-JP作为中性语言。然后提供带有相应卫星的en-US文件夹。

所以我用于本地化和推荐的是:

  1. .vcproj文件中没有<UICulture>en-US</UICulture>
  2. 使用[assembly: NeutralResourcesLanguage("en-US", UltimateResourceFallbackLocation.MainAssembly)]
  3. 为所有目标文化目录提供匹配的卫星。

答案 1 :(得分:2)

我认为任意“更智能”的选择是使用程序集链接器(Al.exe)将.resources文件编译成附属程序集,如article所述。

** 更新 **

该文章中使用的例子:

此程序集链接器(Al.exe)命令从文件strings.de.resources为应用程序MyApp创建附属程序集。

al /t:lib /embed:strings.de.resources /culture:de /out:MyApp.resources.dll

此程序集链接器(Al.exe)命令还从文件strings.de.resources为应用程序MyApp创建附属程序集。 /template选项使附属程序集从父程序集MyApp.dll继承程序集元数据。

al /t:lib /embed:strings.de.resources /culture:de /out:MyApp.resources.dll
/template:MyApp.dll