资源字典是一个受 ResourceDictionary 类支持的概念。SL中所说的资源通常就是指资源字典,而非.resx资源。
哪些对象可以设置为资源:
- 样式和模板。
- 画笔和颜色。
- 故事板动画。
- 变换效果。
- Matrix、Matrix3D 和 Point
- 某些具有可设置和可构造属性的其他结构,如 Thickness 和 CornerRadius(但是,这些结构通常要求在 XAML 中使用初始化文本以便声明有用值
- 在支持代码中定义然后在 XAML 中实例化为资源的自定义类型,如资源的转换器。
- 字符串和基本数值,如 double 和 int。
资源键:
x:Key是推荐使用的资源键设置语法,在SL以前版本中也可以使用x:Name来设置
FrameworkElement.Resources 和 Application.Resources
SL中提供了页面或控件级别的资源,及应用程序级别资源,这样两类资源设置。注意:.Resources属性返回的就是ResourceDictionary类实例。
资源如何被检索到
资源的消费者会首先检查自身的资源,然后是父级的,直到是页面级的,最后是Application级的。一旦检索到,就停止继续检索。
合并资源字典
合并这个概念,记住:不是Copy and paste 把资源都放到一起,而是指把某些资源合并入可被检索的序列中。那么既然各级别资源都可以按照次序被自动检索,为什么还要合并呢?答案就在于从SL3.0开始可以使用单独的资源文件来定义资源。默认的检索序列中当然是不会自动去检索这些外部资源档。所以要使用这些外部资源档就需要把它并入到SL运行时的资源检索序列中来。
<Grid>
<Grid.Resources>
<ResourceDictionary>
<SolidColorBrush Color="#d0157820" x:Key="muddyBrush"/>
<ResourceDictionary.MergedDictionaries>
<ResourceDictionary Source="/rd1.xaml">
<ResourceDictionary Source="/rd2.xaml">
</ResourceDictionary.MergedDictionaries>
</ResourceDictionary>
</Grid.Resources>
....
<Grid>
以上是SL SDK中的示例。 注意几个要点:
l <ResourceDictionary> 之所以需要这个标签,是因为后面要使用<ResourceDictionary.MergedDictionaries>,这是ResourceDictionary对象的属性MergedDictionaries。正是用它来实现具体的外部资源档的引入。
l <ResourceDictionary>内依然可以包含键控资源的定义,如:<SolidColorBrush Color="#d0157820" x:Key="muddyBrush"/>
l <ResourceDictionary.MergedDictionaries>内引入的资源档,在合并之后,后被添加的外部资源档会先被检索,即采用后进先出。
l 合并以后的检索顺序是这样:资源消费对象本身的资源—-页面资源中的键控资源—-页面上合并入的外部资源---应用程序级别资源
应用程序资源和直接资源之间的引用
为应用程序定义的资源不能引用直接资源。这等效于尝试前向引用,因为应用程序资源实际上是最先处理的。但是,任何直接资源都可以引用应用程序资源
资源字典和 XamlReader.Load
使用XamlReader.Load()可以把一段Xaml标签文本让Xaml解析器来解析。在这段标签文本中,如果使用资源,要注意:所有用到的资源必须是在此段标签文本内以键控资源方式来定义的,因为在Xaml解析器解析这段文本的时候不会去检索这段标签文本之外的任何资源。
模板中的 StaticResource
模板在被定义为资源时,模板的定义和应用是分离的。这种情况下要注意:在模板定义中使用的StaticResource资源,必须是在定义的位置就能在资源检索序列中检索到所用的资源。例如在一个控件A上定义的资源,这个控件需要应用一个以资源方式定义的模板,那么在此模板的定义中,就不能使用到A上定义的资源。
在代码中引用资源
在代码中使用FrameworkElement.Resources来引用控件或页面资源;使用Application.Current 或 Application.Resources资源。 运行时可以向控件或页面资源(又称之为直接资源)或应用程序资源内添加资源项。
外部资源字典档案
l 外部资源字典档案以.xaml为扩展名
l 以<ResourceDictionary>为根元素
运行时加载资源字典档案
如果不采用设计时合并资源字典的方式,而是在运行时从代码中加载资源字典档案(使用 Load 以及应用程序服务中的从包加载 API 在运行时加载它),必须把这样加载的资源字典项加入到控件/页面,或应用程序的资源字典中。(例如在Application的StartUp事件处理中把运行时加载的外部资源加入到Application.Resources的资源字典中)