首页 文章

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

提问于
浏览
6

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

我遇到的问题是:

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

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

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

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

Edit (working solution but it seems wrong):

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

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

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

2 回答

  • 2

    由于文档错误,使用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文件夹 .

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

    • .vcproj文件中没有 <UICulture>en-US</UICulture>

    • 使用 [assembly: NeutralResourcesLanguage("en-US", UltimateResourceFallbackLocation.MainAssembly)]

    • 为所有目标文化目录提供匹配的卫星 .

  • 3

    我相信任意"smarter"替代方法是使用程序集链接器(Al.exe)将.resources文件编译成附属程序集,如article中所述 .

    ** Update **

    该文中使用的示例:

    此程序集链接器(Al.exe)命令为该程序创建一个附属程序集应用程序MyApp来自文件strings.de.resources .

    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
    

相关问题