什么是资源
资源是可以在应用程序中的不同位置重复使用的对象。 WPF 支持不同类型的资源。 这些资源主要分为两种类型的资源:XAML 资源和资源数据文件。
静态资源通过查找对已定义资源的引用来为任何 XAML 属性特性提供一个值。 该资源的查找行为类似于编译时查找。
另一方面,动态资源将在初始编译期间创建一个临时表达式,从而推迟资源的查找,直到实际需要请求的资源值才能构造对象。 该资源的查找行为类似于运行时查找,这会影响性能。 在应用程序中尽可能使用静态资源,仅在必要时使用动态资源。
XAML资源
XAML 资源的示例包括画笔和样式,Style(样式)、Trigger(触发器)、Template(模板)、Brush(画笔 )等。
WPF推出了独具特色的对象级资源,每个元素都可以携带自己的资源并可被自己的自己元素共享,XAML资源中的各类模板、程序样式、主题、经常储存在对象资源中。
资源数据文件
资源数据文件是应用程序所需的不可执行的数据文件,通常指添加到应用中的文件,例如内容、数据或嵌入式文件。
对象级资源的定义与查找
WPF的界面元素都具有一个Resources的属性,其类型为ResourceDictionary,能够以“键-值”对的形式存储资源。保存资源时,ResourceDictionary视资源对象为object类型,所以使用资源时需要先对资源进行类型转换。
XAML可以不进行类型转换,因为XAML编译器能够根据标签的Attribute自动识别资源类型,如果类型不对就会抛出异常。C#代码里检索到资源对象后,则需要自己进行类型转换。
//C#中需要自己进行类型转换
//01 在C#中使用定义在XAML代码里的资源
string text = (string)this.FindResource("str");
//02 明确知道资源存放在那个资源字典的写法
string text1 = (string)this.Resources["str"];
this.texTBlock1.Text = text;
<!--01 引入对应的名称空间-->
xmlns:sys="clr-namespace:System;assembly=System.Runtime"
<!--02 在Window.Resources属性里添加两个资源条目,string类型实例、double类型实例-->
<Window.Resources>
<sys:String x:Key="str">
沉舟侧畔千帆过,病树前头万木春。
</sys:String>
<sys:Double x:Key="dbl">
3.1415926
</sys:Double>
</Window.Resources>
<!--03 使用TextBlock消费这些资源-->
<TextBlock Text="{StaticResource str}"/>
<!--04 数据类型不匹配抛出异常,注释掉-->
<!--<TextBlock Text="{StaticResource db1}"/>-->
静态资源和动态资源
资源可引用为静态资源或动态资源。 可通过使用 StaticResource 标记扩展或 DynamicResource 标记扩展创建引用。 标记扩展是 XAML 的一项功能,可以通过使用标记扩展来处理属性字符串并将对象返回到 XAML 加载程序,从而指定对象引用。有关标记扩展行为的详细信息,请参阅 标记扩展和 WPF XAML。
-
静态资源指的是在程序载入内存时对资源的一次性使用,之后就不再访问这个资源,例如:程序的皮肤在运行中始终不变,应使用StaticResource形式使用.
-
动态资源指的是在程序运行中仍然回去访问资源,例如:程序运行中允许用户更改程序皮肤,必须使用DynamicResource形式使用.
二进制资源
-
资源词典里的资源为"WPF资源"或"对象资源",<Application.Resources>中的资源仍然是WPF资源.
-
应用程序的内嵌资源称为:"程序集资源"或"二进制资源"
添加二进制资源
01 创建对应文件夹
02 引入对应文件
03 更改属性为资源或嵌入资源
04 使用Pack URL路径访问二进制资源
<!--XAML代码-->
<Image Source="G:\VsProject\WPF练习\Resources\Resources\1557663177500.jpg"/>
//C#代码 使用缩略写法意味着是相对路径,C#代码中的UriKind必须为Relative,而且根目录可以省略
Uri imgUrl = new Uri(@"G:\VsProject\WPF练习\Resources\Resources\1557663177500.jpg",UriKind.Relative);
//使用完整写法意味着是绝对路径,C#代码中的UriKind必须为Absolute,并且代表根目录不能省略
Uri imgUrl1 = new Uri(@"pack://application;,,,/Resources/Images/Rafale.jpg", UriKind.Absolute);