了解Visual Studio中的资源

Wer*_*eit 7 c# resources visual-studio visual-studio-2012

在Visual Studio中,我有几种方法可以将资源包含到我的项目中:

  1. Solution Explorer→我的项目→右键单击→属性→资源→添加资源
  2. 将文件复制到解决方案目录→解决方案资源管理器→显示所有文件→右键单击→包括在项目中→右键单击→属性→构建操作→ 资源
  3. 将文件复制到解决方案目录→解决方案资源管理器→显示所有文件→右键单击→包含在项目中→右键单击→属性→构建操作→ 嵌入式资源
  4. 多一点?

我的问题是:

  • 这些资源有什么不同?
  • 如何通过代码(C#)访问它们?
  • 是否可以通过代码添加新资源?

Ste*_*nds 8

存储

对于#1,您添加的资源以XML格式存储在一个名为的文件中Resources.resx,该文件通常位于Properties使用默认Visual Studio模板创建的WinForms或WPF应用程序的子文件夹中.

对于#2和#3,资源(文件)包含在项目中(即,Visual Studio项目知道文件,如果适用于项目,它将被添加到源代码控制中等),区别在于在编译器如何包含文件的内容作为结果程序集的一部分.#2通常用于WPF应用程序; WinForms应用程序的#3.


访问

#1(Resources.resx)

通过名为的自动生成的类访问资源Resources.例如,如果添加一个名为的位图资源,则MyBitmap可以按如下方式访问:

System.Drawing.Bitmap bitmap = Properties.Resources.MyBitmap;
Run Code Online (Sandbox Code Playgroud)

#2(构建行动=资源)

可以从XAML(标记)或代码引用资源.对于XAML,一些标准控件支持资源引用.例如,Image控件具有Source默认引用嵌入资源的属性.要引用WPF项目根目录中名为"wpf.jpg"的资源文件:

<Image Source="wpf.jpg" />
Run Code Online (Sandbox Code Playgroud)

如果文件位于名为"images"的子文件夹中:

<Image Source="images/wpf.jpg" />
Run Code Online (Sandbox Code Playgroud)

要从代码访问这些资源,可以使用类的GetResourceStream方法Application,以pack URI的形式传递对所需资源的引用.使用上例中的文件:

Uri path = new Uri("images/wpf.jpg", UriKind.Relative);
StreamResourceInfo ri = Application.GetResourceStream(path);
Stream data = ri.Stream;
Run Code Online (Sandbox Code Playgroud)

获得流后,您可以随心所欲地进行操作.

#3(构建行动=嵌入式资源)

您需要获取对包含资源的程序集的引用,然后调用该GetManifestResourceStream方法以获取它的流.您对流的处理方式取决于您正在处理的资源类型.例如,这将从命名资源创建一个位图:

Bitmap bitmap = new Bitmap(
    System.Reflection.Assembly.GetEntryAssembly()
    .GetManifestResourceStream("resourcename"));
Run Code Online (Sandbox Code Playgroud)

获取正确的资源名称可能很棘手.它通常是程序集名称以及资源的文件夹和文件名的串联.例如,名为"WindowsFormsApplication1"的项目中名为"Resources"的文件夹中名为"MyBitmap.bmp"的文件将被编译为名为的资源WindowsFormsApplication1.Resources.MyBitmap.bmp.这是你传递给GetManifestResourceStream方法的字符串.


添加新资源

由于资源被编译到程序集(EXE或DLL)中,因此如果不重新编译程序集,则无法添加新资源.我所知道的唯一一种编程方式是使用名为Mono.Cecil的NuGet包.