资源的定义与使用

资源与资源字典
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的话也是如此。

posted on 2012-04-15 19:39  WaitingSky  阅读(2719)  评论(3编辑  收藏  举报