[Windows 8|XAML] 應用程式資源(Application Resources)使用與資源字典(ResourceDictionary)的介紹

Published: 10/01/2013, Last Updated: 10/01/2013

前言


前篇中,向各位介紹了如何把XAML元件的屬性做一個重複使用的方式,好處是:

讓你的XAML頁面整齊,捨去重複的程式碼,同時若你要重修調整或修改維護你的XAML程式時,也可以加快你的修改速度(因為你不再需要一個一個去修改)。

而在前篇中我們提到了資源有分兩種:

直接資源(頁面資源)與應用程式資源兩種,而在此篇中,除了再次提一下頁面資源,再來主要會介紹如何使用應用程式資源(Application Resources),與一個新的標籤ResourceDictionary。

直接資源與應用程式資源


直接資源:

FrameworkElement.Resources,或稱頁面資源,是針對單一頁面做資源配置,更詳細的說頁面資源只能被用在單一XAML頁面中的元件使用,在這邊,控制項的元件(Grid、StackPanel等等)都包含Resources屬性(繼承自FrameworkElement),於是我們便可以在Resources標籤中定義我們想要使用的資源;但是一般會建議把資源的定義放在Page,因為Page是XAML頁面的根,所以可以確保我整個頁面下的元件根可能被指定套上資源。

拿下圖來例子看的話,頁面資源分別就是XAML頁面A與頁面B,而頁面A中的資源定義只有頁面A看的到,同理頁面B的資源也只有頁面B的元件看的到,頁面A無法使用頁面B中所定義的資源。

應用程式資源:

Application.Resources,可以使資源的定義被整個Application所看到,如果我在應用程式資源定義的話,上面的頁面A與頁面B,這兩個XAML頁面都可以使用我在應用程式資源事先定義Resources。

使用應用程式資源(Application Resources)


當我們開啟Windows Store App專案後,在專案中你會看到一個App.xaml檔案

點開後你會看到下面這樣的程式碼:

<Application
    x:Class="ResourcesIntro.App"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:local="using:ResourcesIntro">

    <Application.Resources>
        <ResourceDictionary>
            <ResourceDictionary.MergedDictionaries>

                <!-- 
                    定義平台外觀及操作之通用層面的樣式
                    Visual Studio 專案及項目範本的必要項
                 -->
                <ResourceDictionary Source="Common/StandardStyles.xaml"/>
            </ResourceDictionary.MergedDictionaries>

        </ResourceDictionary>
    </Application.Resources>
</Application>

這個App.xaml檔是管理整個你的應用程式相關的資源一些設定,而這邊你也會看到一個關鍵的標籤-Application Resources,所以如果今天我希望在許多個XAML頁面都可以使用到同樣的資源,那麼就可以在這邊去做一個樣式定義。

但是在這邊,你會看到一個新的標籤-ResourceDictionary,這個標籤容我需要好好介紹一下,因為他很重要。

ResourceDictionary(資源字典)


基本上我們在XAML定義資源的時候,是有透過資源字典這個標籤來做管理,資源字典是用來定義資源並管理,透過StaticResources延伸標記參考到的字典物件。

在前篇,我們使用頁面資源(FrameworkElement.Resources)定義樣式時,其實樣式是屬於ResourceDictionary的型態,所以我們才可以對定義好的樣式做StaticResources延伸標記參考(樣式是一種資源,資源是ResourceDictionary類別)

另外,因為ResourceDictionary繼承了IDictionary的介面,所以基本上放入的資源一定要有Key索引鍵值,但是在前篇的第一個範例中,我們對兩個TextBlock做文字顏色的紅色設定時,並未使用到x:key,但他卻沒有出錯!為何?

原因在於,當下我們有指定Style的TargetType為TextBlock,基本上若有設定TargetType,ResourceDictionary的Key值就會套用到TargetType我們所指定的類型,所以即便沒有指定x:key的值也可以(注意!只有Style與Template樣本是這樣的情況)

而在應用程式資源中(Application.Resources),因為預設便加入了ResourceDictionary標籤,所以我們只要把需要加入的樣式放置ResourceDictionary標籤結構內即可,並且透過這個ResourceDictionary使資源能夠在整個應用程式層級的範圍中被保留。

所以這也是ResourceDictionary很重要。

再來,讓我們回到如何使用應用程式資源。

原先XAML頁面資源範例

我們加入了三個TextBlock並透過頁面資源的方式把顏色設定為黃色、紅色、黃色。

 <Grid.Resources>
            <Style TargetType="TextBlock" x:Key="Normal">
                <Setter Property="FontSize" Value="32"/>
                <Setter Property="HorizontalAlignment" Value="Left"/>
                <Setter Property="VerticalAlignment" Value="Top"/>
            </Style>
            <Style TargetType="TextBlock" x:Key="YellowColor" BasedOn="{StaticResource Normal}">
                <Setter Property="Foreground" Value="Yellow"/>
            </Style>
            <Style TargetType="TextBlock" x:Key="RedColor" BasedOn="{StaticResource Normal}">
                <Setter Property="Foreground" Value="Red"/>
            </Style>
</Grid.Resources>
<TextBlock  Margin="310,411,0,0"  Text="TextBlock" Style="{StaticResource YellowColor}"/>
<TextBlock  Margin="677,411,0,0"  Text="TextBlock" Style="{StaticResource RedColor}"/>
 <TextBlock  Margin="983,411,0,0"  Text="TextBlock" Style="{StaticResource YellowColor}"/>

使用Application.Rexoures應用程式資源範例

我把原先的XAML頁面中的樣式資源拿到App.xaml檔案的Application.Resources中,並且我在這邊加入了一個新的空白頁XAML到我的專案中(BlankPage.xaml),同樣指定並且加入三個TextBlock

1.應用程式資源加入樣式

<Application
    x:Class="ResourcesIntro.App"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:local="using:ResourcesIntro">

    <Application.Resources>
        <ResourceDictionary>
            <Style TargetType="TextBlock" x:Key="Normal">
                <Setter Property="FontSize" Value="32"/>
                <Setter Property="HorizontalAlignment" Value="Left"/>
                <Setter Property="VerticalAlignment" Value="Top"/>
            </Style>
            <Style TargetType="TextBlock" x:Key="YellowColor" BasedOn="{StaticResource Normal}">
                <Setter Property="Foreground" Value="Yellow"/>
            </Style>
            <Style TargetType="TextBlock" x:Key="RedColor" BasedOn="{StaticResource Normal}">
                <Setter Property="Foreground" Value="Red"/>
            </Style>
            <ResourceDictionary.MergedDictionaries>

                <!-- 
                    定義平台外觀及操作之通用層面的樣式
                    Visual Studio 專案及項目範本的必要項
                 -->
                <ResourceDictionary Source="Common/StandardStyles.xaml"/>
            </ResourceDictionary.MergedDictionaries>
        </ResourceDictionary>
    </Application.Resources>
</Application>

2.加入BlankPage與TextBlock

<TextBlock  Margin="380,397,0,0"  Text="TextBlock" Style="{StaticResource YellowColor}"/>
<TextBlock  Margin="614,397,0,0"  Text="TextBlock" Style="{StaticResource RedColor}"/>
<TextBlock  Margin="832,397,0,0"  Text="TextBlock" Style="{StaticResource YellowColor}"/>

結果:

兩個XAML檔都使用StaticResources延伸標記參考樣式資源,並且兩個頁面都套用到了樣式!

結論


如果說你有需要再多的XAML頁面中都使用到相同的樣式資源,那麼便可以建議使用應用程式資源來做管理

接下來,還會再向各位介紹另一篇,製作自己的的資源字典檔。

參考資料

ResourceDictionary與XAML資源參考

ResourceDictionary Class

FrameworkElement.Reources Property

Application.Resources

Product and Performance Information

1

Intel's compilers may or may not optimize to the same degree for non-Intel microprocessors for optimizations that are not unique to Intel microprocessors. These optimizations include SSE2, SSE3, and SSSE3 instruction sets and other optimizations. Intel does not guarantee the availability, functionality, or effectiveness of any optimization on microprocessors not manufactured by Intel. Microprocessor-dependent optimizations in this product are intended for use with Intel microprocessors. Certain optimizations not specific to Intel microarchitecture are reserved for Intel microprocessors. Please refer to the applicable product User and Reference Guides for more information regarding the specific instruction sets covered by this notice.

Notice revision #20110804