WPF学习第十集-深入浅出话资源

Posted LisenYang

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了WPF学习第十集-深入浅出话资源相关的知识,希望对你有一定的参考价值。

我们把有用的东西称为资源。“兵马未动,粮草先行”-----程序中的各种数据就是算法的原料和粮草。程序中可以存放数据的地方有很多,可以放在数据库里、可以存储在变量里。介于数据库存储和变量存储之间,我们还可以把数据存储在程序主体之外的文件里。外部文件与程序主体分离,这就有可能丢失或者损坏,编译器允许我们把外部文件编译进程序主体、称为程序主体不可分割的一部分。这就是传统意义上的程序资源(也称为二进制资源)。

WPF不但支持程序级的传统资源,同时还推出了独具特色的对象级资源,每个界面元素都可以携带自己的资源并可被自己的子级元素共享。比如后面的章节我们会讲到模板、程序样式和主题就经常放在对象资源里面。这样一来,在WPF程序中数据就分为4个等级存储了:数据库里的数据相当于存放在仓库里面,资源文件里的数据就相当于放进了旅行箱里,WPF对象资源里面的数据相当于存放在携带的背包里,变量里面的数据相当于拿在手里。

1.1       WPF对象资源的定义和查找

每个WPF界面元素都有一个名为Resource的属性,这个属性继承至FrameworkElement类,其类型为ResourceDictionary。ResourceDictionary能够以键值对的形式存储资源,当要使用到某个资源的时候,使用键值对的形式获取资源对象。在保存资源时,ResourceDictionary视资源对象为Object类型,所以再使用资源时先要对资源对象进行类型转换,XAML编译器能够根据Attribute自动识别资源类型,如果类型不对就会抛出异常,但在C#中检索到资源对象之后,类型转换的事情就只能由我们自己来做了。

ResourceDictionary可以存储任意类型的对象。在XAML代码中向Resource添加资源时需要把正确的命名空间引入到XAML代码中,让我们来看一个例子:

[html]  view plain copy print ?
  1. <Window x:Class="WpfApplication1.Window31"  
  2.         xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"  
  3.         xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"  
  4.         xmlns:sys="clr-namespace:System;assembly=mscorlib"  
  5.         Title="Window31" FontSize="16" SizeToContent="Height">  
  6.     <Window.Resources>  
  7.         <ResourceDictionary>  
  8.             <sys:String x:Key="str">沉舟侧畔千帆过,病树前头万木春。</sys:String>  
  9.             <sys:Double x:Key="db">3.1415926</sys:Double>  
  10.         </ResourceDictionary>  
  11.     </Window.Resources>  
  12.     <StackPanel>  
  13.         <TextBlock Text=" StaticResource ResourceKey=str"></TextBlock>  
  14.         <!--<TextBlock Text="StaticResource ResourceKey=db"></TextBlock>-->  
  15.     </StackPanel>  
  16. </Window>  

首先我们将System命名空间引入XAML代码中并映射为sys名称空间,然后在Windows.Resource里面添加了两个资源条目,一个是string类型,一个是double类型。最后我们用两个textBlock来消费这两个资源(被注释掉的代码因为数据类型不匹配而抛出异常)。程序运行效果如下图:


因为在XAML代码里面可以对集合类容及标签扩展进行简写,所以上面代码更常见的书写格式是这样:

[html]  view plain copy print ?
  1. <Window x:Class="WpfApplication1.Window31"  
  2.         xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"  
  3.         xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"  
  4.         xmlns:sys="clr-namespace:System;assembly=mscorlib"  
  5.         Title="Window31" FontSize="16" SizeToContent="Height">  
  6.     <Window.Resources>  
  7.             <sys:String x:Key="str">沉舟侧畔千帆过,病树前头万木春。</sys:String>  
  8.             <sys:Double x:Key="db">3.1415926</sys:Double>  
  9.     </Window.Resources>  
  10.     <StackPanel>  
  11.         <TextBlock Text=" StaticResource str"></TextBlock>  
  12.         <!--<TextBlock Text="StaticResource ResourceKey=db"></TextBlock>-->  
  13.     </StackPanel>  
  14. </Window>  
再查找资源时,先查找控件自己的Resource属性,如果没有这个资源程序会沿着逻辑树向上一级进行查找,如果连最顶端容器都没有这个资源,程序就会查找Application.Resource(也就是程序的顶级资源)。如果还没有找到,那么就只能抛出异常了。

这就好比每个界面元素都有自己的一个背包,里面可能装有各种各样的资源,使用的时候打开找一找,如果没有找到还可以去翻看上一层控件的背包,直至找到这个资源或报告没有这个资源为止。

如果想在C#代码里面使用XAML代码里面定义的资源,大概格式是这样:

[csharp]  view plain copy print ?
  1. private void Window_Loaded(object sender, RoutedEventArgs e)  
  2.   
  3.     string text = (string)this.FindResource("str");  
  4.     txt0.Text = text;  
  5.   

或者你明确知道资源放在那个资源字典里,就可以这样检索资源:

[csharp]  view plain copy print ?
  1. private void Window_Loaded(object sender, RoutedEventArgs e)  
  2.   
  3.     string text = (string)this.Resources["str"];  
  4.     txt0.Text = text;  
  5.   

你可能会想,如果把资源想CSS或者JS一样放在独立的文件夹里,使用时成套引用、重用时便于分发岂不更好?WPF的资源当然可以做到这一点;ResourceDictionary具有一个名为Source的属性,只要把包含资源定义的文件路径赋值给这个属性就一切搞定了!举个例子,http://wpf.codeplex.com中包含了很多官方/半官方的WPF资源,其中包括WPF工具包和一组非常漂亮的程序皮肤,这些皮肤以资源的形式放在XAML文件中,使用时仅需要将相应的XAML文件添加进项目并使用Source属性进行引用,你的程序就立刻变的光鲜照人。

[html]  view plain copy print ?
  1. <ResourceDictionary Source="ShinyRed.xaml">  
  2.               
  3. </ResourceDictionary>  
运行效果如下图:

1.2         且“动”且“静”用资源

当资源被存储进资源词典之后,我们可以使用两种方式来使用这些资源-----静态方式和动态方式。Static和Dynamic两个词都是我们的老朋友了,当这对词同时出现的时候Static指的是程序的非执行状态而Dynamic指的是程序的运行状态。对于资源的使用,Static和Dynamic也是这个意思。静态资源使用StackResource指的是程序载入内存时对资源的一次性使用,之后就不在去访问这个资源了;动态资源(DynamicResource)使用指的是在程序运行过程中仍然回去访问资源。显然如果你确定某些资源在程序初始化的时候只使用一次、之后不会再改变,就应该使用StaticResource,而程序运行过程中还有可能改变资源应该以DynamicResource形式使用。拿程序的主题来举例,如果程序的皮肤在运行过程中始终不变,以Static形式来使用资源就可以了。如果在程序运行过程中允许用户更改皮肤或者配色方案则必须使用DynamicResource来使用资源。

请看下面这个例子,我在Windows资源字典里放置了两个TextBlock类型资源,并分别以StaticResource和DynamicResource方式使用之:

[html]  view plain copy print ?
  1. <Window x:Class="WpfApplication1.Window32"  
  2.         xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"  
  3.         xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"  
  4.         Title="Window32" FontSize="16" WindowStyle="ToolWindow">  
  5.     <Window.Resources《深入浅出WPF》学习笔记之深入浅出话资源

    SIGAI机器学习第十集 线性判别分析

    SIGAI深度学习第十集 卷积神经网络4

    《深入浅出WPF》学习笔记之深入浅出话事件

    《深入浅出WPF》学习笔记之深入浅出话Binding

    《互联网时代》 第十集 眺望