WPF=Code+Markup 筆記 21

bjq_ren發表於2008-08-10

21 資源

 

WPF的資源有兩種,一種是“元件資源”(assembly resource),是將工程中某些檔案編譯成資源。這是二進位制檔案,如icon和點陣圖,被儲存在元件zhongEXEEXE),並且可以利用Uri物件來存取。

 

另一種是“區域性定義的資源”,因為其定義在XAMLC#中,就如同靜態只讀變數,資源物件在執行時被建立一次,並且被引用它們的element所共享。

 

注:

常量:             const double fontsize = 14;

靜態只讀變數:    static readonly double fontsize = 14;

二者的區別:常量在編譯期間jisuan,並且在編譯期間做值的替代;而靜態只讀變數是在執行期間計算的。

 

所有資源都儲存在一個ResourceDictionary型別的物件中,而且FrameworkElementFrameworkContentElementApplication這三個基本類都定義了一個Resources屬性,而定義在其中的資源,則具有x:Key的屬性。示例如下:

    <StackPanel.Resources>

        <s:Double x:Key="fontsizeLarge">

            18.7

        s:Double>

    StackPanel.Resources>

這裡s表示System名稱空間:xmlns:s="clr-namespace:System;assembly=mscorlib">

 

有兩種使用方式,都牽涉到:

1)屬性元素:

        <Button>

            <Button.FontSize>

                <StaticResource ResourceKey="fontsizeLarge" />

            Button.FontSize>

            Button with large FontSize

        Button>

2)將key放入大括號中:

        <Button FontSize="{StaticResource fontsizeLarge}" >

            Button with small FontSize

        Button>

 

注:在這個大括號中,不可以出現引號;對於字串中出現的大括號,要在此之前,假如一組空的大括號進行轉義:

        <TextBlock Text="{}{Hello World!}" />

 

這些資源要定義在元素的最前端,保證其在被引用之前定義。

 

在一個資源塊中,所有key不能重複,但是在不同級別是可以的。當定位一個資源時,會從這個資源所在位置開始查詢,並沿著這個樹結構向上直到找到這個key為止——這對建立Style很有用。

 

我們也可以將控制元件或element定義為資源,但是隻能使用一次,因為它們只能有一個父親:

            <Button.Resources>

                <Button x:Key="btn" FontSize="24">

                    Button with large FontSize

                Button>

            Button.Resources>

 

 

C#的資源操作程式碼:

            stack.Resources.Add("blueText", new SolidColorBrush(Colors.Blue));

 

 

上述的三個基本類FrameworkElementFrameworkContentElementApplication還定義了FindResource方法,根據key查詢資源,並向上遞迴直到找到為止。

 

 

x:Static標記用來引用類中的靜態屬性/欄位,或者列舉成員。如:

        <Label Content="{x:Static s:SomeClass.SomeStaticProp}" />

這裡要在XAML頭引進:    xmlns:s="clr-namespace:Wpf21"

並在SomeClass類中定義SomeStaticProp靜態欄位,設定它的值,才能在這個XAML中使用SomeClass類。

當然我們還可以使用系統屬性,如Environment.OSVersion

 

注意到,SystemColorsSystemParametersSystemFonts類都有一大堆靜態屬性,XAML可以利用x:Static來取用這些屬性。而且這些靜態屬性都是成對存在的。比如說有一個CaptionFontSize,就有對應的加上key字尾的CaptionFontSizeKey屬性。

        public static double CaptionFontSize { get; }

        public static ResourceKey CaptionFontSizeKey { get; }

 

於是可以這樣使用:

    Background="{StaticResource {x:Static SystemColors.ActiveCaptionBrushKey}}"       

這和

    Background="{StaticResource SystemColors.ActiveCaptionBrush}"       

是等效的。

 

為了讓上面的資源隨著系統配置的改變而相應變化,使用DynamicResource替代StaticResource

    Background="{DynamicResource SystemColors.ActiveCaptionBrush}"       

注:StaticResource中的key被用來存取物件一次,然後物件會被保留;而DynamicResource中的key會被保留,物件需要的時候會被呼叫。這種DynamicResource還能保證資源在使用後再定義也不會出錯。

當然也有特例:先在資源中為Color定義為DynamicResource,然後在XAML中為以StaticResource的方式使用Brush。如下所示:

        <StackPanel.Resources>

            <SolidColorBrush x:Key="dynabrush2"

                Color="{DynamicResource

                    {x:Static SystemColors.ActiveCaptionColorKey}}" />

        StackPanel.Resources>

 

        <Label Foreground="{StaticResource dynabrush2}" />

 

此時,系統顏色的改變,Label也會跟著改變前景色。這是因為SolidColorBrush會跟著Color改變,而Label對這個Brush的引用不會改變。

如果使用方法改變為:

        <Label Foreground="{DynamicResource dynabrush2}" />

則系統顏色的改變不會影響Label的前景色。因為系統顏色的改變導致Label新建一個dynabrush2物件,則重新初始化這個SolidColorBrush,而SystemColors.ActiveCaptionColorKey應該是這個筆刷建構函式的引數。

 

區域性資源定義會覆蓋系統設定。

 

ResourceDictionary檔案的使用,為多個專案提供共享資源。

這些檔案以ResourceDictionary根節點開始,如下MyResources1.xaml

<ResourceDictionary

        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"

來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/15123181/viewspace-422899/,如需轉載,請註明出處,否則將追究法律責任。

相關文章