WPF,Silverlight与XAML读书笔记第十六 资源之二进制资源

说明:本系列基本上是《WPF揭秘》的读书笔记。在结构安排与文章内容上参照《WPF揭秘》的编排,对内容进行了总结并加入一些个人理解。

WPF中的资源特性依赖于核心的.NET资源系统,在此基础之上添加了对另外两种资源类型的支持。分别是二进制资源和逻辑资源。

 

         本节中将首先介绍二进制资源,二进制资源就是其它类型.Net程序中认为的资源,在WPF中可以把编译后的XAML文件作为二进制资源来保存。二进制资源有3种存在形式:

  • 嵌入程序集

  • 在编译时,应用程序已知的松散文件

  • 在编译时,应用程序不知道的松散文件

从另一个角度看,二进制文件可以分为两类:

  • 必须根据当前的文件和语言改变而适应的本地化资源。

  • 不会随文化的改变而改变的资源。

 

定义一个二进制资源的方式

向项目中添加可以作为二进制资源的文件(如一个位图文件)。在此文件的属性面板的生成选项中选择合适的生成方式(参考如下):

适用于二进制资源的生成方式有两种:

  • Resource:将资源放入程序集(或特定语言文化的卫星程序集)中。

  • Content(内容):将这个资源作为一个松散文件。在设置此项的过程中,会向AssemblyAssociatedContentFile中添加一个定制特性,其中记录文件是否存在及其相对位置。

 

注意:二进制资源使用的生成方式是Resource不要误使用为Embedded Resource(嵌入式资源)

如果要把二进制资源保存于松散文件。即使用Content作为生成方式,需要在程序运行时将二进制资源放在适当的位置。松散文件方式的资源的优势有如下两个,仅当你需要这些特性时,才应该使用松散文件,否则应该使用Resource来构建:

  • 松散文件资源可以在程序编译后进行本地化。

  • 松散文件资源可以在程序编译后方便的进行替换。(替换同名文件即可)

 

二进制资源的访问

通常我们在过程式代码及XAML代码中使用URI来访问资源。另外由于转换器的存在我们无需给出完整的URI,而只需一个简单的字符串即可设置。

如下代码所示,这里Image控件引用了作为Resource保存的图片(这里使用了System.Media.ImageSourceConverter这个转换器):

1 <Image Source="logo.gif"></Image>

 

如果将这个资源(logo.gif)生成方式设置为Content,则只需松散文件被复制到应用程序的执行目录即可。

(提示:有关Image控件的详细信息可参见:多媒体控件一文。)

下表列出了XAML中可用的访问二进制资源(假设待访问资源名为logo.jpg)的URI字符串选项(当然访问这些资源需要保证你的程序有足够的权限):

URI格式

资源位置类型

生成方式

logo.jpg

嵌入到当前程序集

Source

嵌入到松散文件

Content

A/B/logo.jpg

使用内部子目录(A\B),(即嵌入程序集内部的目录结构)

Source

松散文件,放在当前可执行文件/XAML文件/程序集的相对子目录 – A\B中

Content

C:\temp\logo.jpg

位于C:\temp目录下的松散文件

Content

file://C:/temp/logo.jpg

C:\temp本地目录下的松散文件

Content

\\pc1\images\logo.jpg

位于\\pc1\images   UNC共享目录下的松散文件

 

http://cnblogs.com/logo.jpg

位于cnblogs站点上的松散文件

 

MyDll;Component/logo.jpg

嵌入到另一个叫做MyDll的程序据或者可执行文件中的资源

 

MyDll;Component/A/B/logo.jpg

编译到名为MyDll程序集或可执行文件的内部子目录结构(A\B)下的资源

 

pack://siteOfOrigin:,,,/logo.jpg

位于部署位置的松散文件

 

pack://siteOfOrigin:,,,/A/B/logo.jpg

位于部署位置的A\B子目录下的松散文件

 

 

 注意:已编译的XAML文件不能通过简单的文件名引用当前目录下的二进制资源(除非这个资源文件被添加到项目)。

推荐的解决方案是使用上述列表中最后的那种设置方式,即:pack://siteOfOrigin:,,,/logo.jpg,这种以部署目录为根的设置方式。 

 注意:上述表格中列出的部分资源位置是位于UNCwww中,而WPF会以同步方式访问这些文件,所以如果由于网速等原因无法访问这些文件将会导致引用挂起。 

 

下面重点分析上述表格中最后两大类资源访问方式。

  1. 访问另一个程序集中的嵌入式资源。

其语法是:AssemblyReference; Component/Resource

其中AssemblyReference表示一个特定的程序集,其可以被设置成4种形式。

AssemblyName

AssemblyName; vVersionNumberv前缀必须)

AssemblyName;PublicKeyToken

AssemblyName; vVersionNumber;PublicKeyToken

  1. 访问部署位置中的资源

利用部署位置确定资源的路径有更强的通用性(尤其是对于一些部分可信任程序集,可以保证其能访问到所需的资源)。

部署位置资源所使用的语法是一种标准的Pack URI格式语法。即pack://siteOfOrigin,,,/为前缀的格式。下文将详细说明这种语法格式。

Pack URI

这种资源定位符使用pack://packageURI/partPath的格式。来定位一个资源,这其中:

  • pack://是一个固定的前缀
  • packageURI是一个内嵌的URI,这其中将反斜杠变为逗号;如我们定位一个文件使用file:///C:/doc.xps,转化为packageURI后就成了file:,,,C:,doc.xps
  • partPath:是资源的名称(或者包含一个相对目录)

往往在XAML中我们只需写partPath,而转换器会自动生成完整的Pack URI。在C#中如果要定位一个资源则需自己书写Pack URI。如下面这个C#的例子:       

Image image = new Image();
image.Source = new   BitmapImage(new   Uri("pack://application:,,,/logo.jpg"));

 

 

本地化

关于本地化的作用不再赘述,这里详细描述实现WPF资源本地化的方法。

  1. 实现多文化项目

为了指定资源的默认文化,自动构造相应的Satelite程序集,需要在项目文件(.proj文件)xml文件中添加一个UICulture结点。(UICulture应该被添加到对应于构造配置(DebugRelease)PropertyGroup元素,参见如下示例:)

1 <Project   ToolsVersion="3.5" DefaultTargets="Build" xmlns="…   …">
2   <PropertyGroup>
3 <UICulture>zh-CN</UICulture>

 

完成这步操作后重新生成项目会出现一个包含名为AssemblyName.Resource.dll的程序集的名为zh-CN的文件夹。

另外需要在项目中AssemblyInfo.cs文件中添加一条Attribute – NeutralResourcesLanguage,并给其设置一个与程序默认文化一致的值,如:

[assembly:   NeutralResourcesLanguage("zh-CN",UltimateResourceFallbackLocation.Satellite)]

 

  1. 对每一个需要进行本地化的元素添加一个x:Uid标签(Attribute)(可以看出这个Attribute位于XAML语言的命名空间),其值需要被设置为一个唯一的标识符。

可以使用msbuild工具快速完成这个任务,命令如下:

msbuild   /t:updateuid ProjectName.csproj

 

  1. 使用LocalBaml创建新的Satellite程序集

再次编译项目,然后使用LocalBamlWindows SDK工具之一),打开构建过程生成的资源文件(位于obj\Debug下,名称形如ProjectName.g.zh-CN.resourcesg代表generated),然后使用如下命令生成一个包含所有需要本地化的属性值的CSV文件:

LocBaml   /parse ProjectName.g.zh-CN.resources /out:zh-CN.csv

这样我们可以翻译这个文件,并将翻译后的结果另存为en-US.csv(假设是英语)。

接下来,可以使用如下命令由en-US.csv生成一个对应文化的程序集资源文件。

LocBaml   /generated ProjectName.resources.dll /trans:en-US.csv /cul:en-US

 

最后只需要将新生成的文件放置于主程序集中以文化命名的文件夹中(这里就是en-US)。

提示:测试不同的文件,可以设置

System.Threading.Thread.CurrentThread.CurrentUICultureSystem.Threading.Thread.CurrentThread.CurrentCulture

为一个想要的CultureInfo实例。

 

 

本文完

 

参考:

WPF揭秘》

 

原文地址:https://www.cnblogs.com/lsxqw2004/p/4616647.html