星空雅梦

WPF教程(六)二进制资源

WPF除了上节静态资源和动态资源,还有其它类型资源。学会如何添加使用会让我们编程变得更加游刃有余。

二进制资源其实是一些传统的资源项,比如位图,音频文件,视频文件,松散文件(LooseFile)等等。对于这些资源项我们可以将其存储为松散文件,或者编译进程序集中。

如何向程序集添加二进制文件,先讲讲添加字符串二进制文件,步骤如下:

(1)点击Resources.resx ;(2)添加字段;(3)将访问修饰符改为:Public

  1.  
    <Window x:Class="OtherResources.MainWindow"
  2.  
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
  3.  
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
  4.  
    xmlns:res="clr-namespace:OtherResources.Properties"
  5.  
    Title="MainWindow" Height="350" Width="525">
  6.  
    <Grid>
  7.  
    <TextBlock Text="{x:Static res:Resources.UserName}"/>
  8.  
    </Grid>
  9.  
    </Window>

上述是添加二进制字符串文件,在日常的开发中,肯定会用到图片、音频之类的文件,一般操作相信大家看到已经掌握,但我们往往会忽视其构建模式(生成操作)。

Resource:将资源放入程序集中(如果是有本地化支持的话会编译到对应语言集的子程序集中)。其中有一个Embedded Resource(嵌入式资源)和Resource,这两者都会在应用程序中嵌入一个程序集资源,但WPF无法通过Uri引用在xaml和C#里对这个文件进行使用,所以不建议。

Content:将这个资源作为一个松散文件加入到程序集中,程序集会记录对应的文件是否存在及其路径。它跟完全松散文件有区别,完全松散文件程序集并不知道有这个文件存在,在程序运行时才会去访问这个路径获取资源。

如果构建模式是Resource,那么复制到输出目录应该选择不复制(虽然可以选择复制,但毫无意义,系统运行不依赖这些文件),这比较适合一次性使用不需要更改的小型文件,不至于程序很庞大;如果构建模式是Content,复制到输出目录必须选择始终赋值或较新则复制,否则无论前台或后台获取,程序运行都会找不到资源。因此,当打包.exe执行文件时,前者不需要拷贝资源文件与执行文件放在一起,但Content需要,否则无法使用该资源,并在保证资源文件名称前后一致的前提下,可以替换内容,适合尚未决定使用的大型文件。

Resource和Content资源运用,主要是通过统一资源标识Uri(Unified Resource Identifier)来标识和访问资源,既可以前台直接获取,也可以在后台隐藏访问,都是通过"pack://application:,,,/xx.png"表示当前项目的资源。

  1.  
    <Window x:Class="OtherResources.MainWindow"
  2.  
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
  3.  
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
  4.  
    Title="MainWindow" Height="350" Width="525">
  5.  
    <Grid>
  6.  
    <WrapPanel>
  7.  
    <Button Width="100" Name="Btn1" Margin="20,0,0,0" Height="25">
  8.  
    <!--相对路径-->
  9.  
    <Image Source="Resources/xx.png" Stretch="fill"/>
  10.  
    <!--绝对路径-->
  11.  
    <!--<Image Source="pack://application:,,,/Resources/xx.png" Stretch="fill"/>-->
  12.  
    </Button>
  13.  
    <Button Width="100" Name="Btn2" Margin="20,0,0,0" Height="25">
  14.  
    <!--相对路径-->
  15.  
    <Image Source="Resources/xx.png" Stretch="fill"/>
  16.  
    <!--绝对路径-->
  17.  
    <!--<Image Source="pack://application:,,,/Resources/xx.png" Stretch="fill"/>-->
  18.  
    </Button>
  19.  
    </WrapPanel>
  20.  
    </Grid>
  21.  
    </Window>

当然我们可以在后台获取:

  1.  
    <Window x:Class="OtherResources.MainWindow"
  2.  
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
  3.  
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
  4.  
    Title="MainWindow" Height="350" Width="525">
  5.  
    <Grid>
  6.  
    <WrapPanel>
  7.  
    <Button Width="100" Name="Btn1" Margin="20,0,0,0" Height="25">
  8.  
    <Image x:Name="image1" Stretch="Fill"/>
  9.  
    </Button>
  10.  
    <Button Width="100" Name="Btn2" Margin="20,0,0,0" Height="25">
  11.  
    <Image x:Name="image2" Stretch="Fill"/>
  12.  
    </Button>
  13.  
    </WrapPanel>
  14.  
    </Grid>
  15.  
    </Window>
  1.  
    public MainWindow()
  2.  
    {
  3.  
    InitializeComponent();
  4.  
    image1.Source = new BitmapImage(new Uri(@"Resources/xx.png", UriKind.Relative));//相对路径
  5.  
    image2.Source = new BitmapImage(new Uri(@"Resources/xx.png", UriKind.Relative));
  6.  
    //image1.Source = new BitmapImage(new Uri(@"pack://application:,,,/Resources/xx.png"));////绝对路径
  7.  
    //image2.Source = new BitmapImage(new Uri(@"pack://application:,,,/Resources/xx.png"));
  8.  
    }

如何运用完全松散文件(代码未自动生成任何标记,程序运行时才知道),"pack://SiteOfOrigin:,,,/Resources/xx.png",可以获取任何独立于程序的松散文件,甚至可以跨程序集获取资源。一般情况,生成操作选择无或Content,复制到输出目录选择始终赋值或较新复制。而且,跟Content一样,也可以通过同命名来换内容。

  1.  
    //使用SiteOfOrigin只有绝对路径,没有相对路径
  2.  
    <Image Source="pack://SiteOfOrigin:,,,/Resources/xx.png" Width="50" Height="50"/>
  3.  
    //或者后台
  4.  
    // image1.Source = new BitmapImage(new Uri(@"pack://SiteOfOrigin:,,,/Resources/xx.png"));

若WPF需要引用外部项目资源的方法 WPF中如果你使用的资源文件不是本程序集的,是另外的程序集,就可以这样做(其它引用,包括SiteOfOrigin、后台,方式都像前面一样,这里只是内容有变化): 1.引用要用的程序集,pack://application:,,,/程序集名称;component/路径 ,其中pack://application:,,,可以省略 示例:

  1.  
    <Image Source="pack://application:,,,/Skin;component/Resources/xx.png"/>
  2.  
    //或直接相对路径
  3.  
    <Image Source="/Skin;component/Resources/xx.png"/>

总结

WPF中的资源有两种,一种称为“程序集资源”( assembly resources)或者“二进制资源”(binary resources),在MSDN中将其称为“应用程序数据文件”(application data files);另外一种称为资源或者对象资源(object resources)、“逻辑资源”(logic resources),甚至“声明式资源”(declarative resources)。统称前者为程序集资源,本章开头所介绍的。后者为逻辑资源,上一章节的动态、静态资源。

关于"pack://application:,,,/xx.png",无论相对路径还是绝对路径,pack://application:,,,所到达的目录层是程序源文件所在文件夹,必须是指定自动生成的Resources文件夹或Resources再下级,否则报错;"pack://SiteOfOrigin:,,,/Resources/xx.png",只有绝对路径,pack://SiteOfOrigin:,,,到达的文件层是Debug,只要保证Debug下有引用的资源文件,即可获取,不指定Resources文件夹。

与直接把资源放置在程序运行目录不同的是,添加Content资源文件,会向程序集(AssemblyAssociatedContentFile)中添加一个定制特性,该程序集记录文件是否存在及其相对位置,这就是与引用完全松散文件的区别。

完全松散的文件指那些没有添加到项目中,只是拷贝在程序目录中的文件。有关二进制资源先介绍到这里,还是比较详细的,下一章我们再介绍其它资源

原文地址:https://www.cnblogs.com/LiZhongZhongY/p/10870429.html