闲话WPF之十三(WPF中的资源)
在WPF中,资源的含义和处理方式与传统的Win32和Windows Forms资源有所区别。首先,不需要创建.resx文件,只需要在工程中指出资源即可,其它所有的工作都由WPF完成。其次,WPF中的资源不再像.NET中有资源ID,在XAML中引用资源需要使用Uri。最后,在WPF的资源中,几乎可以包含所有的任意CLR对象,只要对象有一个默认的构造函数和独立的属性。在WPF本身的对象中,可以声明如下四种对象:Style、Brushes、Templates和DataSource。
在定义具体的资源之前,我们先考虑如下几个相关的问题:
1、资源的有效范围:在WPF中,所有的框架级元素(FrameworkElement或者FrameworkContentElement)都有一个Resource属性。也就是说。我们可以在所有这类元素的Resource子元素中定义属性。在实践中,最常用的三种就是三种根元素所对应的资源:Application、Page和Window。顾名思义,在Application根元素下定义的资源将在当前整个应用程序中可见,都可以访问。在Page和Window中定义的元素只能在对应的Page和Window中才能访问。
2、资源加载形式:WPF提供了两种资源类型:Static资源和Dynamic资源。
两种的区别主要有两点:A)、Static资源在编译时决议,而Dynamic资源则是在运行时决议。B)、Static资源在第一次编译后即确定了相应的对象或者值。此后不能对其进行修改,即使修改成功也是没有任何意义的,因为其它使用资源的对象不会得到通知。Dynamic资源不同,它只有在运行过程中真正需要时,才会在资源目标中查找。所以我们可以动态的修改Dynamic资源。显而易见,Dynamic资源的运行效率将比Static资源低。
3、不管是Static资源还是Dynamic资源,所有的资源都需要设置Key属性:x:Key=”KeyName”。因为WPF中的资源没有资源ID,需要通过资源Key来标识以方便以后访问资源。范围资源时我们根据资源的类型使用StaticResource或者DynamicResource标记扩展。
好了,对WPF中的资源所有了解后,我们看一些简单的例子:
<Window
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">
<StackPanel>
<StackPanel.Resources>
<SolidColorBrush x:Key="MyBrush" Color="gold"/>
</StackPanel.Resources>
<TextBlock Foreground="{StaticResource MyBrush}" Text="Text"/>
</StackPanel>
</Window>
在这个例子中,我们在StackPanel元素的Resource子元素中定义了一个SolidColorBrush资源。然后在后面通过StaticResouce标记扩展,利用前面的x:Key属性访问定义好的资源。
资源除了可以在XAML声明外,还可以通过代码进行访问控制。支持Resource属性的对象都可以通过FindResource、以及Resource.Add和Resource.Remove进行控制:
<Window
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">
<Window.Resouce>
<SolidColorBrush x:Key="MyBrush" Color="gold"/>
</Window.Resouce>
</Window>
我们先在代码XAML的Window.Resource中定义了一个MyBrush。在代码中可以如下对其进行访问:
SolidColorBrush brush = this.FindResource("MyBrush") as SolidColorBrush;
如果需要进一步修改或者删除资源时,可如下编码:
this.Resouce.Remove(“MyBrush”); //删除MyBrush资源
this.Resouce.Add(“MyBrush”); //重新动态添加资源
说明:以上三处的this引用都是特指我们定义MyBrush的元素Window。读者朋友可根据实际情况修改。