- A+
一、WPF支持程序级资源(也称为二进制资源),和对象级资源。
二、对象级资源简介
- 简介:对象级资源主要是被应用到各个界面元素中,而每个WPF界面元素都具有一个Resource属性,这个属性继承自FrameworkElement类,其类型为ResourceDictionary(ResourceDictionary是以"键-值"的形式存储资源,通过索引找到资源并应用)。
- 对象级资源的应用场景主要分为三个:
① Application的对象级资源:每新建一个WPF应用,就会自动生成一个App.xaml,这个文件最常用的特性是定义全局资源,这些资源会在整个应用里面被使用。
1 <Application> 2 <Application.Resources> 3 <TextBlock x:Key="Res1" Text="Hello"/> 4 </Application.Resources> 5 </Application>
② 界面元素的对象级资源:可放在任一控件的Resource属性中,但通常将其放在界面的根元素上,起生效范围是当前界面。
1 <Window> 2 < Window.Resources> 3 <TextBlock x:Key="Res1" Text="Hello"/> 4 </ Window.Resources> 5 </Window>
③ 将对象级资源封装成外部资源字典:将对象级资源统一放在资源字典中,在需要使用的地方将其集成,一般都在App.xaml中对资源进行集成。
1 <UserControl> 2 <UserControl.Resources> 3 <ResourceDictionary Source="Res/ControlForDemo.xaml"/> 4 </UserControl.Resources> 5 </UserControl>
而资源字典的内容如下:
1 <ResourceDictionary xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" 2 xmlns:local="clr-namespace:DependencyPropertyDemo.Res"> 3 <TextBlock x:Key="Res1" Text="Fighting" x:Shared ="False"/> 4 </ResourceDictionary>
- x:Shared = "true":对每次请求的资源都使用同个实例。
- x:Shared = "false":对每次请求的资源都创建一个新的实例。详细解析:WPF学习之四:x:Shared概述 - 潮儿 - 博客园 (cnblogs.com)
- 资源字典的编译选项:page或者Resource。
—— page:可以保证XAML资源文件最终被编译为baml文件,然后可以作为资源插入到.NET框架中,在运行时,框架引擎提取并解析.baml,然后创建一个相应的WPF视觉树或工作流。
—— Resource:可以嵌入到程序集中,但是不被编译,其解析速度会稍微慢一点。
三、资源字典的集成
- XAML集成外部资源字典
1 <UserControl> 2 <UserControl.Resources> 3 <ResourceDictionary> 4 <ResourceDictionary.MergedDictionaries> 5 <ResourceDictionary Source="Res/ButtonStyle.xaml"/> 6 <ResourceDictionary Source="Res/TextBoxStyle.xaml"/> 7 </ResourceDictionary.MergedDictionaries> 8 </ ResourceDictionary> 9 </UserControl.Resources> 10 </UserControl>
ResourceDictionary.MergedDictionaries:该属性是一个ResourceDictionary对象的集合,可以使用这个集合提供多个资源文件。注意:MergedDictionaries下面的每一个ResourceDictionary都必须是独立的,多个ResourceDictionary之间不可以相互引用;ResourceDictionary中定义的key是先进后出的,所以获取到的顺序和定义的顺序是相反的。
- C#后台代码集成外部资源字典
this.Resources.MergedDictionaries.Add(new ResourceDictionary() { Source = new System.Uri("pack://application:,,,/AddResourceFile;component/Res/TextBoxStyle.xaml") });
四、对象级资源的使用
- 在XAML中使用资源
1 <StackPanel HorizontalAlignment="Center" VerticalAlignment="Center"> 2 <Label Content="{StaticResource Res1}" HorizontalAlignment="Center"/> 3 <Label Content="{DynamicResource Res2}" HorizontalAlignment="Center"/> 4 </StackPanel>
① StaticResource:仅在程序载入内存时访问该资源一次;
② DynamicResource:程序在运行过程中每次使用都会重新访问该资源;
- 在C#后台代码中使用资源
1 private void Button_Click(object sender, RoutedEventArgs e) 2 { 3 this.label1.Content = this.Resources["Res1"]; 4 this.label2.Content = this.FindResource("Res2"); 5 }
① FindResource:如果找不到请求的资源,会引发异常;
② Resources:获取本地的资源,找不到没有异常;
五、对象级资源的检索方式
- 首先是查找控件自己的Resource属性,若查不到,会沿着逻辑树一级级的查找父控件的Resource属性;
- 若在父级控件中都查不到,就会去查找Application的Resource属性;
- 若仍然查找不到,则会异常处理。