您的位置:首页 > 其它

Silverlight(WPF)知识随手记[3]:对资源的初步认识

2011-03-28 15:23 155 查看
  在WPF程序中数据分为四个等级存储:数据库里面的数据、资源文件里面的数据、WPF对象资源里面的数据以及变量中的数据。首先要了解下WPF对象级资源的定义与使用。

1、WPF对象级资源的定义与查找
  每个WPF界面元素都具有一个名为Resources的属性,这个属性继承自FrameworkElement类,其类型是ResourceDictionary。ResourceDictionary能够以"Key-Value"对的形式来存储资源。在保存资源时,ResourceDicitionary视资源为object类型,所以在使用资源时先要对资源对象进行类型转换。
  ResourceDictionary可以存储任意类型的对象。在XAML代码中向Resources添加资源时老板娘把正确的名称空间引入到XAML代码中,如下面的代码:

<Window x:Class="Test.Window1"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:sys="clr-namespace:System;assembly=mscorlib"
Title="Test" Height="100" Width="300"
>
<Window.Resources>
<ResourceDictionary>
<sys:String x:Key="str">
测试资源的使用
</sys:String>
</ResourceDictionary>
</Window.Resources>
<StackPanel>
<TextBlock Text="{StaticResource ResourceKey=str}" Margin="5"/>
</StackPanel>
</Window>


  执行结果:
  


  首先要将System命名空间引入XAML代码并映射为sys名称空间,然后在Window.Resources属性里面添加资源条目。因为在XAML代码中可以对集合类型内容及标签扩展进行简写,所以上面代码可以修改其中一行为:

<TextBlock Text="{StaticResource str}" Margin="5"/>


  在检索资源时,先查找控件自己的Resources属性,如果没有这个资源程序会沿着逻辑树向上一级控件查找,如果连最项层容器都没有这个资源,程序就会去查找Application.Resources,如果找不到,就抛出异常。如果想在c#代码中使用定义在XAML代码里面的资源,格式为:

string text=(string)this.FindResource("str");
this.textBlock1.Text=text;


  如果你明确知道资源放在哪的资源词典里面,就可以这样检索资源:

string text=(string)this.Resources["str"];
this.textBlock1.Text=text;


  ResourceDictionary具有一个Source的属性,只要把包含资源定义的文件路径赋值给这个属性就能成套引用或者重用。例如,http://wpf.codeplex.com中包含很多官方/半官方的WPF资源,其中包括WPF工具包和一组非常漂亮的皮肤,这些皮肤以资源的形式放在XMAL文件中,使用时仅需要把相应的XAML文件添加进项目并使用Source属性进行引用。如:

<Window.Resources>
<ResourceDictionary Source="ShinyRed.xaml"/>
</Window.Resources>


  推荐参考:http://silverlightchina.net/html/tips/2010/0102/528.html
  

2、资源的使用方式:
  当资源被存储进资源词典后(Windows.Resource),我们可以通过下面的两种方式来使用这些资源:
  静态与动态方式,StaticResource是指在程序载入内存时对资源的一次性使用,之后就不会再去访问这个资源;DynamicResource是指在程序运行过程中仍然会去访问资源。所以,如果我们可以确定某些资源只在程序初始化的时候使用一次就应该使用StaticResource,而程序运行时还有可能改变的资源应该以DynamicResource形式使用。例如程序的皮肤,如果程序皮肤的颜色在运行中始终不变,以StaticResource方式来使用就可以,如果程序运行时允许用户更改时就应该以DynamicResource方式来使用资源(像迅雷7那样的动态换肤?)。
  

<Window.Resources>
<TextBlock
x:Key="res1"
Text="静态与动态调用资源的区别" />
<TextBlock
x:Key="res2"
Text="静态与动态调用资源的区别" />
</Window.Resources>
<StackPanel>
<Button Margin="4" Content="{StaticResource res1}" />
<Button Margin="4" Content="{DynamicResource res2}" />
<Button Margin="4" Content="更新动态资源"  Click="Button_Click"/>
</StackPanel>

void Button_Click(object sender, RoutedEventArgs e)
{
//这里我们动态的修改了资源的内容,所以除非是以DynamicResource的方式来调用
//相应的资源才会改变
this.Resources["res1"]=new TextBlock(){Text="资源更新后"};
this.Resources["res2"]=new TextBlock(){Text="资源更新后"};
}



-> ->


3、二进制资源的添加与访问
  为了不把资源词典里面的资源和应用程序内嵌的资源搞混,我们明确称呼资源词典里面的资源为“WPF资源”或“对象资源”,称呼应用程序的内嵌资源为“程序集资源”或“二进制资源”。另外,WPF程序中写在<Application.Resources/>标签内的资源依然是WPF资源而不是二进制资源。
  如果要添加的资源是字符串,我们可以使用应用程序Properties名称空间中的Resources.resx资源文件。Resources.resx文件内容的组织形式也是“键-值”对,编译后,Resources.resx会形成Properties名称空间中的Resources类,使用类的方法或属性获取资源。
  要使用Resources.resx中的资源,先要把程序的Properties名称空间映射为XAML名称空间,然后使用x:Static标签扩展来访问资源:

xmlns:prop="clr-namespace:ResourceSample.Properties"

<Textblock Text="{x:Static prop:Resources.KeyWord}"/>


  使用Resources.resx最大的好处是便于程序的国际化、本地化。
  如果添加的资源不是字符串而是图标、图片之类的外部文件,仅需要简单地通过右键新建文件夹将其加入项目即可。

  Tips:如果要让外部文件编译进目标成为二进制资源,必须在属性窗口中把文件的BuildAction属性值设为Resource,另外Copy to Output Directory属性就设为Do not copy,反之亦然。
  
  WPF通过Pack URI路径来访问二进制资源,格式如下:

pack://application,,,[/程序今本名称;][可选版本号;][文件夹名称/]文件名称


  实际上pack:/application,,,可以省略,程序集名称和版本号常使用缺省值,所以我们可以简单的写。需要注意到是相对路径与绝对路径的区别。

  4、补充资源
  收集更新中。

  参考资源:读书笔记,MSDN
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: