文章目录
WPF资源
什么叫WPF的资源(Resource)?
根据《深入浅出WPF》,首先理解以下“程序资源”:编程语言编译器可以实现将应用程序使用到的外部文件编译进程序主体(dll或者exe)、称为程序不可分割的一部分,这部分被编译进程序主体的外部文件,我们可以称之为“程序资源”。
资源是保存在可执行文件中的一种不可执行数据。而对于WPF应用程序而言,WPF资源几乎可以包含图像、字符串等所有的任意CLR对象,只要对象有一个默认的构造函数和独立的属性。也就是说,应用程序中非程序代码的内容,比如点阵图、颜色、字型、动画/影片档以及字符串常量值,可将它们从程序中独立出来,单独包装成"资源(Resource)"。有了资源,我们就可以在xaml中或者后台C#代码中使用这些资源,例如给元素的属性赋值,如设定元素的某些属性值,设定模板,设定Style。
使用资源的优势:
- 由于不用写在程序代码中,方便管理:便于更新。
- 优化资源,节省空间。资源一旦定义,便可重复利用。还记得FLASH中的将物体转换为元件吗?一旦将物体转换为元件,就可以重复利用了。在WPF中,似乎与之有共通之处。所不同的是,WPF将资源保存在XAML中,对我们而言是“可见的”。
以上转载自博客。
0.WPF支持的资源形式或者说分类
主要转载自博客:
1.二进制资源(binary resource)
- Resource:将资源嵌入程序集中,WPF将相关资源打包到.Resources文件,然后再由编译器嵌入到程序集文件中
- Content:资源不会嵌入到程序集,仅仅在程序集清单中添加一条记录。资源文件必须随其他程序集文件一起部署到目标目录。
- Loose File:这类资源通常是运行期动态确定或加入的
2.逻辑资源(logical resource)
- xaml各个元素的Resource属性
- 资源字典ResourceDictionary
3.resx资源(同winform相同)
这里先仅了解逻辑资源。逻辑资源不仅可以定义文本、图片资源等,甚至可以定义一个完整的子元素。 每个WPF UI元素都有Resources属性。
我理解的逻辑资源包括(我认为的,包含在Page、Window、UserControl、类似Button这样的UI控件的Resource属性中的资源和ResourceDictionary中的资源,这些资源应该至少可以是以下这些东西):
- Style标签
- Template
- 类似SolidColorBrush这样的可以作为控件的属性值的标签
- 还有ResourceDictionary.MergedDictionary
- 其他。但是我不知道具体还有什么
1.资源层级有四个等级
- 物件(应该是指控件)级:
- 只能套用在这个对象物件或者其子物件(应该是指控件)中(没理解)
- 定义范围:
- 文件级
- 可套用到这个文件中的所有物件(应该是指控件),如< Window.Resources>
- 定义范围:Windows或者Page层级的xaml
- 应用程序级
- 定义范围:App.xaml
- 可以套用在程序的任何地方
- 字典级
- 定义范围:把资源封装成一个资源字典, 定义到ResourceDictionary的XAML文件中(没理解)
- 可以在另一个应用程序中重复使用
由于每个元素都有自己的资源集合,WPF中资源的寻找是通过WPF元素树进行递归搜索的。
2.合并资源字典到Resource属性
逻辑资源也可以集中放在资源字典ResourceDictionary中。
<ResourceDictionary>
<ContentControl x:Key="label1">Hello, World!</ContentControl>
<ContentControl x:Key="label2">Hello, C#!</ContentControl>
</ResourceDictionary>
通过合并资源字典把资源字典的资源添加到Resource属性
<Window.Resources>
<ResourceDictionary>
<ResourceDictionary.MergedDictionaries>
<ResourceDictionary Source="Dictionary1.xaml" />
</ResourceDictionary.MergedDictionaries>
</ResourceDictionary>
</Window.Resources>
或者
<Window.Resources>
<ResourceDictionary Source="src.xaml" />
</Window.Resources>
3.关于静态StaticResource和动态Resource
目前确认的是,在窗体的xaml中使用Window.Resource来声明的资源,在后面的控件中进行引用时,可以使用如下两种方式进行引用:
Style="{StaticResource MySelfDefineStyle}"
或者
Style="{StaticResource ResourceKey=MySelfDefineStyle}"
Style="{DynamicResource MySelfDefineStyle}"
或者
Style="{DynamicResource ResourceKey= MySelfDefineStyle}"
当我们说静态和动态资源的时候,应该指对资源的使用方式,所以我猜测逻辑资源可以通过静态资源引用或者动态资源引用的方式引用(但我奇怪,我们似乎是在说资源的分类本身包括静态和动态两种,而非引用方式)。
这两种方式的引用,根据网上的说法,我认为主要区别在于静态资源不可修改,动态资源允许修改(静态资源修改了,界面显示上也不会有反应)。静态资源使用是指在程序载入内存时对资源的一次性使用。
4.关于资源字典ResrouceDictionary
暂不研究
5.后台代码FindResource方法能查找到什么范围内的资源
每个UI元素都有自己的FindResource方法。
目前猜测控件元素的FindResource方法检索资源的方式:
程序对一个控件对象检索(查找)资源时,会先查控件自己的Resoources属性,如果没有这个资源,程序会沿着逻辑树向上一级控件查找,如果连最顶层的容器(我猜是类似Window、Page这类),程序就会去查找Application.Resources(程序的最顶级资源),如果没有找到则抛异常。(这里的程序不知道是不是指编译器)。
如果知道资源就在某个元素的Resources中,那么可以直接调用这个函元素的.Resource[“key”]进行检索。
6使用Pack URI路径访问二进制资源(抄自《深入浅出WPF》)
xaml中的使用的格式是:
pack://application:,,,[程序集名称;][版本号;][文件夹名称/]资源文件名
示例:
<Image x:Name="ImageTest" Source="pack://application:,,,/Resource/Images/Rafale.jpg">
然后,由于pack://application:可以省略,后面的程序集名称、版本号常使用缺省值,因此可以写成:
<Image x:Name="ImageTest" Source="/Resource/Images/Rafale.jpg">
这里的文件路径应该是程序启动目录的相对路径
C#中示例:
Uri uri = new Uri(@"Resource/Images/Rafale.jpg",UriKind.Absolute);
this.ImageTest.Source = new BitMapImage(uri)