WPF教程(六)二进制资源
2018年08月06日 20:36:51 yangwenxue1989 阅读数:80WPF除了上节静态资源和动态资源,还有其它类型资源。学会如何添加使用会让我们编程变得更加游刃有余。
二进制资源其实是一些传统的资源项,比如位图,音频文件,视频文件,松散文件(LooseFile)等等。对于这些资源项我们可以将其存储为松散文件,或者编译进程序集中。
如何向程序集添加二进制文件,先讲讲添加字符串二进制文件,步骤如下:
(1)点击Resources.resx ;(2)添加字段;(3)将访问修饰符改为:Public
- <Window x:Class="OtherResources.MainWindow"
- xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
- xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
- xmlns:res="clr-namespace:OtherResources.Properties"
- Title="MainWindow" Height="350" Width="525">
- <Grid>
- <TextBlock Text="{x:Static res:Resources.UserName}"/>
- </Grid>
- </Window>
上述是添加二进制字符串文件,在日常的开发中,肯定会用到图片、音频之类的文件,一般操作相信大家看到已经掌握,但我们往往会忽视其构建模式(生成操作)。
Resource:将资源放入程序集中(如果是有本地化支持的话会编译到对应语言集的子程序集中)。其中有一个Embedded Resource(嵌入式资源)和Resource,这两者都会在应用程序中嵌入一个程序集资源,但WPF无法通过Uri引用在xaml和C#里对这个文件进行使用,所以不建议。
Content:将这个资源作为一个松散文件加入到程序集中,程序集会记录对应的文件是否存在及其路径。它跟完全松散文件有区别,完全松散文件程序集并不知道有这个文件存在,在程序运行时才会去访问这个路径获取资源。
如果构建模式是Resource,那么复制到输出目录应该选择不复制(虽然可以选择复制,但毫无意义,系统运行不依赖这些文件),这比较适合一次性使用不需要更改的小型文件,不至于程序很庞大;如果构建模式是Content,复制到输出目录必须选择始终赋值或较新则复制,否则无论前台或后台获取,程序运行都会找不到资源。因此,当打包.exe执行文件时,前者不需要拷贝资源文件与执行文件放在一起,但Content需要,否则无法使用该资源,并在保证资源文件名称前后一致的前提下,可以替换内容,适合尚未决定使用的大型文件。
Resource和Content资源运用,主要是通过统一资源标识Uri(Unified Resource Identifier)来标识和访问资源,既可以前台直接获取,也可以在后台隐藏访问,都是通过"pack://application:,,,/xx.png"表示当前项目的资源。
- <Window x:Class="OtherResources.MainWindow"
- xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
- xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
- Title="MainWindow" Height="350" Width="525">
- <Grid>
- <WrapPanel>
- <Button Width="100" Name="Btn1" Margin="20,0,0,0" Height="25">
- <!--相对路径-->
- <Image Source="Resources/xx.png" Stretch="fill"/>
- <!--绝对路径-->
- <!--<Image Source="pack://application:,,,/Resources/xx.png" Stretch="fill"/>-->
- </Button>
- <Button Width="100" Name="Btn2" Margin="20,0,0,0" Height="25">
- <!--相对路径-->
- <Image Source="Resources/xx.png" Stretch="fill"/>
- <!--绝对路径-->
- <!--<Image Source="pack://application:,,,/Resources/xx.png" Stretch="fill"/>-->
- </Button>
- </WrapPanel>
- </Grid>
- </Window>
当然我们可以在后台获取:
- <Window x:Class="OtherResources.MainWindow"
- xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
- xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
- Title="MainWindow" Height="350" Width="525">
- <Grid>
- <WrapPanel>
- <Button Width="100" Name="Btn1" Margin="20,0,0,0" Height="25">
- <Image x:Name="image1" Stretch="Fill"/>
- </Button>
- <Button Width="100" Name="Btn2" Margin="20,0,0,0" Height="25">
- <Image x:Name="image2" Stretch="Fill"/>
- </Button>
- </WrapPanel>
- </Grid>
- </Window>
- public MainWindow()
- {
- InitializeComponent();
- image1.Source = new BitmapImage(new Uri(@"Resources/xx.png", UriKind.Relative));//相对路径
- image2.Source = new BitmapImage(new Uri(@"Resources/xx.png", UriKind.Relative));
- //image1.Source = new BitmapImage(new Uri(@"pack://application:,,,/Resources/xx.png"));////绝对路径
- //image2.Source = new BitmapImage(new Uri(@"pack://application:,,,/Resources/xx.png"));
- }
如何运用完全松散文件(代码未自动生成任何标记,程序运行时才知道),"pack://SiteOfOrigin:,,,/Resources/xx.png",可以获取任何独立于程序的松散文件,甚至可以跨程序集获取资源。一般情况,生成操作选择无或Content,复制到输出目录选择始终赋值或较新复制。而且,跟Content一样,也可以通过同命名来换内容。
- //使用SiteOfOrigin只有绝对路径,没有相对路径
- <Image Source="pack://SiteOfOrigin:,,,/Resources/xx.png" Width="50" Height="50"/>
- //或者后台
- // image1.Source = new BitmapImage(new Uri(@"pack://SiteOfOrigin:,,,/Resources/xx.png"));
若WPF需要引用外部项目资源的方法 WPF中如果你使用的资源文件不是本程序集的,是另外的程序集,就可以这样做(其它引用,包括SiteOfOrigin、后台,方式都像前面一样,这里只是内容有变化): 1.引用要用的程序集,pack://application:,,,/程序集名称;component/路径 ,其中pack://application:,,,可以省略 示例:
- <Image Source="pack://application:,,,/Skin;component/Resources/xx.png"/>
- //或直接相对路径
- <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)中添加一个定制特性,该程序集记录文件是否存在及其相对位置,这就是与引用完全松散文件的区别。
完全松散的文件指那些没有添加到项目中,只是拷贝在程序目录中的文件。有关二进制资源先介绍到这里,还是比较详细的,下一章我们再介绍其它资源