WPF 程序集资源

程序集资源,是指嵌入程序内部的二进制资源,如文本、图片、视频、声音和松散文件(Loose file)等等,对于这些资源项我们可以将其存储为松散文件或者编译进程序集中。这与传统的.NET程序其实是相通的。

1、将资源放入程序集中

将资源添加到应用程序中,非常简单,在当前程序目录下,建立一个文件夹,如下图所示:

image

取名任意,我们叫Assets,在Assets添加几个图片1.png,2.png,3.png,如图:

image

我们在界面上,添加一个Image控件,则代码如下:

<Canvas>
     <Image Source="Assets/1.png"></Image>
</Canvas>

运行可以看到结果,如下图所示:

image

图片被引入当前应用程序中,那么我们看看编译完成的程序,是什么样的呢?

image

可以看出,得到的结果程序,并没有assets目录,而是图片被编译到应用程序中,我们使用Reflector查看程序,可以看到

image

图片被编译到程序中,并且建立了一个baml的文件,我们看看baml的定义:

BAML含义为二进制应用标记语言(Binary Application Markup Language),BAML是XAML被解析,标记化后的二进制形式.虽然XAML可以由程序代码来实现,但是XAML转换成BAML的过程中不会产生程序代码。所以BAML和MSIL不同,它只是一种被压缩的声明格式,在装载(load)和解析方面要优于XAML,并且文件体积也比XAML小。BAML本身没有对外公布,所以以后版本中的BAML的和现在可能会有所不同。   

2、资源的编译方式

上一节,我们看到了,图片资源被编译到应用程序内部,那么是由什么来控制这些编译的呢,我们可以在项目中选择图片,则可以看到选中的图片下面有一个生成操作,如图:

image

这些生成操作,可以分别说明如下:

无:不在项目输出组中包含该文件,并且在生成进程中不会对其进行编译。例如包含文档的文本文件,如项目自述文件、说明文件等。发布之后它就没有了。如App.config文件。

内容(Content) :不编译该文件,但将其包含在“内容”(Content) 输出组中。例如,此设置是 .htm 或其他类型 Web 文件的默认值。 不编译,但是发布之后会原样输出。这个方式,可以用来指定比较松散的界面资源,如图片,用户可以更换图片的方式,更换软件界面。

我们也可以通过URL来访问这个资源。

<Image Source="Images/sl.png" />

编译:只适合代码。

嵌入的资源(Embedded Resource):将该文件作为 DLL 或可执行文件嵌入主项目生成输出中。此设置通常用于资源文件。例如NHibernate的映射文件,嵌入的资源无法通过Uri引用在xaml和C#里对这个文件进行使用,不建议在WPF采用这种方式在程序集里嵌入资源。这种资源需要通过如下方式获取资源:

Reflection.Assembly.GetExecutingAssembly().GetManifestResourceStream(string path)

ApplicationDefinition:程序的入口xaml文件(默认就是App.xaml)应该设置为这个"应用定义"。其他文件都不适合用这个。

Page:不适合用于资源文件。所有的用户控件,页面和子窗体(Usercontrol/Page/Childwindow)的xaml文件应该采用的生成操作。 如果改为别的方式那么会导致后台对应的代码文件无法链接到这个xaml文件。 采用"Page" build action时xaml里的错误会导致工程无法正确生成。

CodeAnalysisDictionary:代码分析可用。

Resource:资源会被打包在程序集内部。 选择这种生成方式后,该资源文件会被嵌入到该应用的程序集中,就是说打开生成的xap是看不到这个文件的。 可以用相对于当前的XAML文件的相对Uri访问,<Image Source="sl.png" />或是<Image Source="./sl.png" />, 在子文件夹里的可以用<Image Source=”./images/ sl.png” />访问到。最保险的方式是采用特有的程序集资源URI访问,格式为 <Image Source="/{assemblyShortName};component/ sl.png "/>,这种方式还可以引用到xap中的其他程序集中的图片。这种生成方式的系统资源可以直接用Application.GetResourceStream(uri).Stream在代码里来得到。

(前面的案例就是采用这种方式)。

SplashScreen:"SplashScreen"是这个选项是WPF的启动画面使用的。

3.Resources.resx资源

基于文本的格式是特定于.NET 框架的 XML 格式,称为 ResX(.resx 文件),这种资源和前面的编译不太一样,.resources 扩展名来自于在将 .resx 文件作为资源嵌入之前 Visual Studio .NET 处理该文件时所使用的工具。工具名称是 resgen.exe,它用来将 .resx XML 格式“编译”为二进制格式。可以手动将 .resx 文件编译成 .resources 文件,如下所示: 

C:> resgen.exe Resource1.resx;

.resx会形成Properties名称空间中的Resource类,使用Resource类来访问资源,那么,我们设置为.resx的资源,则不能通过Uri访问,访问.resx的资源,需要通过访问静态类Resource的成员,如以下代码:

<Image Source="{x:Static  prop:Resource.iconpng}" ></Image>

.resx和编译资源中的Resource的选择

  • 假如是图片、视频等资源不需要发生改变和动态切换的,我推荐通过编译Resource的方式,可以通过Uri进行访问资源,且在代码和xaml中都可以灵活使用。
  • .resx比较适合文本和需要变化的图片等信息,切信息需要动态切换的,比如根据不同语言加载不同资源。也适合多个应用程序共享一个资源的情况,可以生成一个resources.dll文件

 

原文地址:https://www.cnblogs.com/minhost/p/7575137.html