资源的定义与使用
资源与资源字典
Windows Phone 7通过ResourceDictionary类提供了提供了资源字典的概念。资源字典是一个按键索引的对象字典。可以在XAML中后台代码中使用。资源字典可以存在于应用程序结构中的多个位置,包括直接资源、应用程序资源(App.xaml)或作为XAML中独立存在。使用资源字典要明确哪些对象应该放在资源字典里。其实,真正需要共享的就可以放在资源字典中。
Silverlight ResourceDictionary 共享行为支持以下对象类别的可共享用法(摘自:http://msdn.microsoft.com/zh-cn/library/cc903952(VS.95).aspx):
- 样式和模板。
- 画笔和颜色。
- 包括演示图板的动画类型。
- 转换。
- Matrix、Matrix3D 和 Point 结构值。
- 某些具有可设置和可构造属性(例如 Thickness 和 CornerRadius)的其他结构。
- 支持代码中定义自定义类型,然后在 XAML 中实例化做为资源。 这样的例子针对资源、数据源的 CLR 对象、或实现 IValueConverter 数据绑定的转换器。
- 字符串和基本数值,如 double 和 int。
设置资源设置时,可以设置一个整体的,也可以设置一个部分的。比如,我们可以设置一个样式资源<style>,这里可以包括Margin、Height等一系列的属性设置,我们也可以设置其中某一个属性,比如Margin属性的设置需要的类型是Thickness,我们可以设置一个<Thickness>的资源来表示Margin的属性。当然,有时候会出现这样的情况,比如说在布局设计的时候,规定了一个控件的宽和高,在引用资源的时候资源设置中也规定了控件的宽和高,这个时候,会以我们设置的宽和高为主,也就是前者。
创建并使用资源的四种方式
方式一:创建并使用全局资源
找到全局文件App.xaml,在App.xaml中存在标签<Application.Resources>,这里就是定义资源的地方。
在App.xaml中的<Application.Resources>我们可以定义需要使用的资源,但是每一个资源必须制定属性“x:key”来唯一标识此资源。当然,放在App.xaml中的资源可以被应用程序中的各个部分使用,如不同页面,不同后台代码。
在前台代码中,我们可以使用StaticResource扩展标记,直接引用已定义的资源,在后台时,我们需要使用形如“Application.Current.Resources["greenStyle"] as Style”的方式来使用资源。如定义如下资源:
<!--应用程序资源--> <Application.Resources> <!--定义TextBlock的资源样式,分别为红色、20字体,绿色、40字体--> <Style x:Key="redStyle" TargetType="TextBlock"> <Setter Property="Foreground" Value="Red" /> <Setter Property="FontSize" Value="20" /> </Style> <Style x:Key="greenStyle" TargetType="TextBlock"> <Setter Property="Foreground" Value="Green" /> <Setter Property="FontSize" Value="40" /> </Style> <!--定义字符串资源--> <sys:String x:Key="myName">sky</sys:String> </Application.Resources>
注意:在定义String等字符串或值的资源时,需要引入命名空间 xmlns:sys="clr-namespace:System;assembly=mscorlib",否则不能使用。
我们在前台代码中,写一个TextBlock来显示资源myName,使用Button来在后台更改TextBlock的Style属性。如:
<!--ContentPanel - 在此处放置其他内容--> <Grid x:Name="ContentPanel" Grid.Row="1" Margin="12,0,12,0"> <TextBlock Height="56" HorizontalAlignment="Left" Margin="76,68,0,0" Name="myInfo" Text="TextBlock" VerticalAlignment="Top" Width="320" Style="{StaticResource redStyle}"/> <Button Content="点击显示信息" Height="72" HorizontalAlignment="Left" Name="btnShowInfo" VerticalAlignment="Top" Width="259" Margin="76,195,0,0" Click="btnShowInfo_Click" /> </Grid>
后台代码为:
private void btnShowInfo_Click(object sender, RoutedEventArgs e) { this.myInfo.Text =Application.Current.Resources["myName"] as String; if (this.myInfo.Style == (Application.Current.Resources["redStyle"] as Style)) { this.myInfo.Style = Application.Current.Resources["greenStyle"] as Style; } else { this.myInfo.Style = Application.Current.Resources["redStyle"] as Style; } }
这样,我们可以得到这样的效果:当页面加载时,TextBlock的值是“TextBlock”,Style属性是红色、20字体,当点击的时候,Textblock的值为“sky”,它的Style的属性会在红色、20字体与绿色、40字体间切换。
方式二:创建并使用局限于本页面的资源
我们可以将资源的定义不写在App.xaml中,而是在某一个页面中添加一个<phone:PhoneApplicationPage.Resources>标签,在这个页面中使用这里定义的资源。如,我们可以再页面中定义这样的资源:指定Button的Margin布局为“76,195”,背景色为蓝色。
<phone:PhoneApplicationPage.Resources> <Thickness x:Key="myMargin"> 76,195 </Thickness> <Style x:Key="myButton" TargetType="Button"> <Setter Property="Background" Value="Blue"/> </Style> </phone:PhoneApplicationPage.Resources>
在这个页面的布局中设置Button的Margin属性和Style属性。代码与效果图为:
<Button Content="点击显示信息" Height="72" HorizontalAlignment="Left" Name="btnShowInfo" VerticalAlignment="Top" Width="259" Margin="76,195,0,0" Style="{StaticResource myButton}" Click="btnShowInfo_Click" />
综合方式一与方式二,效果运行为:
一般的,对于一个较大的项目,很有可能的场景是将很多需要的资源放在一个文件中统一管理,其他的应用程序或者dll在需要资源时调用就行了,这时就会使用资源字典文件了,如下面的方式三和方式四。
方式三:创建并使用独立的XAML中的资源字典文件
在我们定义资源的时候,我们可以新建一个xaml文件,在这个文件中定义我们需要的资源,如果我们直接新建一个Windows Phone Application的页面,它会自动生成后台文件,也就是生成.cs文件,我们需要将这个文件删除。之后,在xaml中定义我们的资源,格式为:
<ResourceDictionary xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"> <!--定义的资源--> </ResourceDictionary>
在这里,我们新建一个文件名为“Page1.xaml”,在里面书写代码:
<ResourceDictionary xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"> <!--定义Button的字体大小--> <Style x:Key="myStyle" TargetType="Button"> <Setter Property="FontSize" Value="32"/> <Setter Property="Foreground" Value="Red"/> </Style> </ResourceDictionary>
然后,在App.xaml中做一下类似于声明的操作,字面意思理解起来就是说明我的资源文件在哪里,格式:
<!--应用程序资源--> <Application.Resources> <ResourceDictionary> <ResourceDictionary.MergedDictionaries> <ResourceDictionary Source="Page1.xaml"/> </ResourceDictionary.MergedDictionaries> </ResourceDictionary> </Application.Resources>
然后就可以像其他方式一样使用了。如:
<Button Content="Button" Height="103" HorizontalAlignment="Left" Margin="66,88,0,0" Name="button1" Style="{StaticResource myStyle}" VerticalAlignment="Top" Width="191" />
效果为:
在这里还有一些小插曲,我们稍后再说。
方式四:定义并使用外部DLL文件资源字典文件
这个方式就是其实就是创建并生成一个DLL文件,在需要使用的时候加载就行了。
创建一个项目,使用Windows Phone Class Library(即Windows Phone类库)来创建,名为“ResourceDll”。删除项目中默认的Class1.cs文件,创建一个新的“myResource.xaml”文件。写入信息。如:
<ResourceDictionary xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"> <!--定义Button的字体大小--> <Style x:Key="myStyle" TargetType="Button"> <Setter Property="FontSize" Value="32"/> <Setter Property="Foreground" Value="Red"/> </Style> </ResourceDictionary>
之后生成解决方案,系统就会在obj/Debug下就会生成一个DLL文件,这里生成的是
在需要使用这里的资源的时候,我们需要在项目的“引用”里面引用这个“ResourceDll”文件,然后在App.xaml中做出声明,但是Source的写法会不一样,如:
<ResourceDictionary> <ResourceDictionary.MergedDictionaries> <ResourceDictionary Source="/ResourceDll;component/myResource.xaml"/> </ResourceDictionary.MergedDictionaries> </ResourceDictionary>
然后就可以在项目的任意地方使用了,这个的用法和方式三的使用是一致的,当然我们可以在一个页面中做这样的声明来局限在一个页面中。
注意:如果我们有两个资源文件,分别为:Page1.xaml和Page2.xaml,如我们新建一个Page2.xaml,代码为
<ResourceDictionary xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"> <!--定义Button的字体大小--> <Style x:Key="myStyle2" TargetType="Button"> <Setter Property="FontSize" Value="20"/> <Setter Property="Foreground" Value="Green"/> </Style> </ResourceDictionary>
那么在App.xam中的设置为
<!--应用程序资源--> <Application.Resources> <ResourceDictionary> <ResourceDictionary.MergedDictionaries> <ResourceDictionary Source="Page1.xaml"/> <ResourceDictionary Source="Page2.xaml"/> </ResourceDictionary.MergedDictionaries> </ResourceDictionary> </Application.Resources>
而在使用的时候,只要使用相应的x:key值就行了,如两个Button分别使用为:
<Grid x:Name="ContentPanel" Grid.Row="1" Margin="12,0,12,0"> <Button Content="Button" Height="103" HorizontalAlignment="Left" Margin="66,88,0,0" Name="button1" Style="{StaticResource myStyle}" VerticalAlignment="Top" Width="191" /> <Button Content="Button" Height="103" HorizontalAlignment="Left" Margin="66,197,0,0" Name="button2" Style="{StaticResource myStyle2}" VerticalAlignment="Top" Width="191" /> </Grid>
效果为:
这样就有一个问题来了,如果我们两个资源文件中的x:key定义的是相同的,那系统怎么判断。经过笔者的判断,系统会自动使用做App.xaml时最后声明的资源字典文件,如果在Page2.xaml中的Style也命名为myStyle,那么系统使用的是 <ResourceDictionary Source="Page2.xaml"/>这个文件。若我们为上述两个Button都指定Style为myStyle,效果:
反之如果App.xaml中的设置为
<Application.Resources> <ResourceDictionary> <ResourceDictionary.MergedDictionaries> <ResourceDictionary Source="Page2.xaml"/> <ResourceDictionary Source="Page1.xaml"/> </ResourceDictionary.MergedDictionaries> </ResourceDictionary> </Application.Resources>
效果则变为:
另外,如果我们在做了上述的对资源文件的引用之后,如果我们还在<Application.Resources>标签中做资源定义的话会报错的,笔者分析系统不知道怎么引用资源了,(如果园友有解决办法的话记得说一下,谢谢!)所以笔者觉得如果要使用资源文件的话就不要自定义资源了。引用DLL的话也是如此。