21章 资源
WPF的资源有两种,一种是“组件资源”(assembly resource),是将工程中某些文件编译成资源。这是二进制文件,如icon和位图,被储存在组件zhong(EXE或EXE),并且可以利用Uri对象来存取。
另一种是“局部定义的资源”,因为其定义在XAML或C#中,就如同静态只读变量,资源对象在运行时被建立一次,并且被引用它们的element所共享。
注:
常量: const double fontsize = 14;
静态只读变量: static readonly double fontsize = 14;
二者的区别:常量在编译期间jisuan,并且在编译期间做值的替代;而静态只读变量是在运行期间计算的。
所有资源都存储在一个ResourceDictionary类型的对象中,而且FrameworkElement、FrameworkContentElement、Application这三个基本类都定义了一个Resources属性,而定义在其中的资源,则具有x:Key的属性。示例如下:
<StackPanel.Resources>
<s:Double x:Key="fontsizeLarge">
18.7
s:Double>
StackPanel.Resources>
这里s表示System命名空间:xmlns:s="clr-namespace:System;assembly=mscorlib">
有两种使用方式,都牵涉到:
1)属性元素:
<Button>
<Button.FontSize>
<StaticResource ResourceKey="fontsizeLarge" />
Button.FontSize>
Button with large FontSize
Button>
2)将key放入大括号中:
<Button FontSize="{StaticResource fontsizeLarge}" >
Button with small FontSize
Button>
注:在这个大括号中,不可以出现引号;对于字符串中出现的大括号,要在此之前,假如一组空的大括号进行转义:
<TextBlock Text="{}{Hello World!}" />
这些资源要定义在元素的最前端,保证其在被引用之前定义。
在一个资源块中,所有key不能重复,但是在不同级别是可以的。当定位一个资源时,会从这个资源所在位置开始查找,并沿着这个树结构向上直到找到这个key为止——这对建立Style很有用。
我们也可以将控件或element定义为资源,但是只能使用一次,因为它们只能有一个父亲:
<Button.Resources>
<Button x:Key="btn" FontSize="24">
Button with large FontSize
Button>
Button.Resources>
C#的资源操作代码:
stack.Resources.Add("blueText", new SolidColorBrush(Colors.Blue));
上述的三个基本类FrameworkElement、FrameworkContentElement、Application还定义了FindResource方法,根据key查找资源,并向上递归直到找到为止。
x:Static标记用来引用类中的静态属性/字段,或者枚举成员。如:
<Label Content="{x:Static s:SomeClass.SomeStaticProp}" />
这里要在XAML头引进: xmlns:s="clr-namespace:Wpf21"
并在SomeClass类中定义SomeStaticProp静态字段,设定它的值,才能在这个XAML中使用SomeClass类。
当然我们还可以使用系统属性,如Environment.OSVersion。
注意到,SystemColors、SystemParameters、SystemFonts类都有一大堆静态属性,XAML可以利用x:Static来取用这些属性。而且这些静态属性都是成对存在的。比如说有一个CaptionFontSize,就有对应的加上key后缀的CaptionFontSizeKey属性。
public static double CaptionFontSize { get; }
public static ResourceKey CaptionFontSizeKey { get; }
于是可以这样使用:
Background="{StaticResource {x:Static SystemColors.ActiveCaptionBrushKey}}"
这和
Background="{StaticResource SystemColors.ActiveCaptionBrush}"
是等效的。
为了让上面的资源随着系统配置的改变而相应变化,使用DynamicResource替代StaticResource。
Background="{DynamicResource SystemColors.ActiveCaptionBrush}"
注:StaticResource中的key被用来存取对象一次,然后对象会被保留;而DynamicResource中的key会被保留,对象需要的时候会被调用。这种DynamicResource还能保证资源在使用后再定义也不会出错。
当然也有特例:先在资源中为Color定义为DynamicResource,然后在XAML中为以StaticResource的方式使用Brush。如下所示:
<StackPanel.Resources>
<SolidColorBrush x:Key="dynabrush2"
Color="{DynamicResource
{x:Static SystemColors.ActiveCaptionColorKey}}" />
StackPanel.Resources>
<Label Foreground="{StaticResource dynabrush2}" />
此时,系统颜色的改变,Label也会跟着改变前景色。这是因为SolidColorBrush会跟着Color改变,而Label对这个Brush的引用不会改变。
如果使用方法改变为:
<Label Foreground="{DynamicResource dynabrush2}" />
则系统颜色的改变不会影响Label的前景色。因为系统颜色的改变导致Label新建一个dynabrush2对象,则重新初始化这个SolidColorBrush,而SystemColors.ActiveCaptionColorKey应该是这个笔刷构造函数的参数。
局部资源定义会覆盖系统设定。
ResourceDictionary文件的使用,为多个项目提供共享资源。
这些文件以ResourceDictionary根节点开始,如下MyResources1.xaml:
<ResourceDictionary
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
来自 “ ITPUB博客 ” ,链接:http://blog.itpub.net/15123181/viewspace-422899/,如需转载,请注明出处,否则将追究法律责任。
转载于:http://blog.itpub.net/15123181/viewspace-422899/