天天看點

WPF的靜态資源(StaticResource)和動态資源(DynamicResource)

靜态資源(StaticResource)和動态資源(DynamicResource)

資源可以作為靜态資源或動态資源進行引用。這是通過使用 StaticResource 标記擴充或 DynamicResource 标記擴充完成的。

      StaticResource 通過替換已定義資源的值來為 XAML 屬性提供值。

      DynamicResource 通過将值推遲為對資源的運作時引用來為XAML 屬性提供值。動态資源引用強制在每次通路此類資源時都重新進行查找。

      通常來說,不需要在運作時更改的資源使用靜态資源;而需要在運作時更改的資源使用動态資源。動态資源需要使用的系統開銷大于靜态資源的系統開銷。例如以下的例子:

1: <Window x:Class="WPFResource.StaticAndDynamicResource"      
2:     xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"      
3:     xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"      
4:     Title="StaticAndDynamicResource" Height="200" Width="300">      
5:     <Window.Resources>      
6:         <SolidColorBrush x:Key="ButtonBrush" Color="Red" />      
7:     </Window.Resources>      
9:     <StackPanel>      
10:         <Button Margin="5" Content="Static Resource Button A" Background="{StaticResource ButtonBrush}" />      
11:         <Button Margin="5" Content="Static Resource Button B" Background="{StaticResource ButtonBrush}">      
12:             <Button.Resources>      
13:                 <SolidColorBrush x:Key="ButtonBrush" Color="Yellow" />      
14:             </Button.Resources>      
15:         </Button>      
16:         <Button Margin="5" Content="Change Button Resource" Click="Button_Click" />      
17:         <Button Margin="5" Content="Dynamic Resource Button A" Background="{DynamicResource ButtonBrush}" />      
18:         <Button Margin="5" Content="Dynamic Resource Button B" Background="{DynamicResource ButtonBrush}">      
19:             <Button.Resources>      
20:                 <SolidColorBrush x:Key="ButtonBrush" Color="Yellow" />      
21:             </Button.Resources>      
22:         </Button>      
23:     </StackPanel>      
24: </Window>      
1: private void Button_Click(object sender, RoutedEventArgs e)      
2: {      
3:     SolidColorBrush brush = new SolidColorBrush(Colors.Green);      
4:     this.Resources["ButtonBrush"] = brush;      
5: }      

以上的例子在運作時顯示如下:

WPF的靜态資源(StaticResource)和動态資源(DynamicResource)

而點選“Change Button Resource”按鈕後,顯示的結果為:

WPF的靜态資源(StaticResource)和動态資源(DynamicResource)

從程式執行的結果來看,我們可以得到如下的結論:

  • 靜态資源引用是從控件所在的容器開始依次向上查找的,而動态資源的引用是從控件開始向上查找的(即控件的資源覆寫其父容器的同名資源)
  • 更改資源時,動态引用的控件樣式發生變化(即"Dynamic Resource Button A"發生變化)

如果要更改"Dynamic Resource Button B"的背景,需要在按鈕的事件中添加以下代碼(将"Dynamic Resource Button B"的控件的x:Name設定為"btn4")

1: SolidColorBrush brushB = new SolidColorBrush(Colors.Blue);      
2: this.btn4.Resources["ButtonBrush"] = brushB;      

執行的結果如下:

WPF的靜态資源(StaticResource)和動态資源(DynamicResource)

靜态資源引用最适合于以下情況:

  • 您的應用程式設計幾乎将所有的應用程式資源集中到頁或應用程式級别的資源字典中。靜态資源引用不會基于運作時行為(例如重新加載頁)進行重新求值,是以,根據您的資源和應用程式設計避免大量不必要的動态資源引用,這樣可以提高性能。
  • 您正在設定不在 DependencyObject 或 Freezable 上的屬性的值。
  • 您正在建立将編譯為 DLL 并打包為應用程式的一部分或在應用程式之間共享的資源字典。
  • 您正在為自定義控件建立一個主題,并定義在主題中使用的資源。對于這種情況,通常不需要動态資源引用查找行為,而需要靜态資源引用行為,以使該查找可預測并且獨立于該主題。使用動态資源引用時,即使是主題中的引用也會直到運作時才進行求值,并且在應用主題時,某個本地元素有可能會重新定義您的主題試圖引用的鍵,并且本地元素在查找中會位于主題本身之前。如果發生該情況,主題将不會按預期方式運作。
  • 您正在使用資源來設定大量依賴項屬性。依賴項屬性具有由屬性系統啟用的有效值緩存功能,是以,如果您為可以在加載時求值的依賴項屬性提供值,該依賴項屬性将不必檢視重新求值的表達式,并且可以傳回最後一個有效值。該方法具有性能優勢。
  • 您需要為所有使用者更改基礎資源,或者需要通過使用 x:Shared 屬性為每個使用者維護獨立的可寫執行個體。

動态資源最适合于以下情況:

  • 資源的值取決于直到運作時才知道的情況。這包括系統資源,或使用者可設定的資源。例如,您可以建立引用由 SystemColors、SystemFonts 或 SystemParameters 公開的系統屬性的 setter 值。這些值是真正動态的,因為它們最終來自于使用者和作業系統的運作時環境。您還可以使用可以更改的應用程式級别的主題,在此情況下,頁級别的資源通路還必須捕獲更改。
  • 您正在為自定義控件建立或引用主題樣式。
  • 您希望在應用程式生存期調整 ResourceDictionary 的内容。
  • 您有一個存在依存關系的複雜資源結構,在這種情況下,可能需要前向引用。靜态資源引用不支援前向引用,但動态資源引用支援,因為資源直到運作時才需要進行求值,是以,前向引用不是一個相關概念。
  • 從編譯或工作集角度來說,您引用的資源特别大,并且加載頁時可能無法立即使用該資源。靜态資源引用始終在加載頁時從 XAML 加載;而動态資源引用直到實際使用時才會加載。
  • 您要建立的樣式的 setter 值可能來自受主題或其他使用者設定影響的其他值。
  • 您正在将資源應用到元素,而在應用程式生存期中可能會在邏輯樹中重新設定該元素的父級。更改此父級還可能會更改資源查找範圍,是以,如果您希望基于新範圍對重新設定了父級的元素的資源進行重新求值,請始終使用動态資源引用。

不同類型的資源

1、程式集資源。這種常見于将圖檔設定到程式集中,做為程式集的資源。

程式集資源在定義時,将檔案複制到解決方案-項目所在的目錄或其子目錄中,并将檔案的屬性中的Build Action設定為Resource。(注意,WPF不支援項目屬性中的資源)

WPF的靜态資源(StaticResource)和動态資源(DynamicResource)

然後在XAML檔案中使用如Image的Source屬性,指定到此檔案:

1: <StackPanel Background="#FFC7DAFF">      
2:     <TextBlock Margin="5" Text="Assembly Resource" />      
3:     <Image Margin="5" Source="Image/Users.png" Width="32" Height="32" />      
4:     <Button Margin="5">      
5:         <Button.Content>      
6:             <StackPanel Orientation="Horizontal">      
7:                 <Image Margin="5" Source="Image/Users.png" Width="32" Height="32" />      
8:                 <TextBlock Text="My Button" VerticalAlignment="Center" />      
9:             </StackPanel>      
10:         </Button.Content>      
11:     </Button>      
12: </StackPanel>      

此項目編譯後,在Assembly中将封裝該圖檔檔案。此種方法适用于較小的資源。

2、對象資源

除剛剛我們使用的圖檔做為程式集資源外,前面例子中所使用的資源均是對象資源。系統對于對象資源使用ResouceDictionary這個字典集合處理,其Key對應即x:Key聲明的鍵,Value對應資源。我們前面使用的都是SolidColorBrush對象,再例如使用字元串及ImageBrush對象做為資源:

1: <StackPanel Background="#FFE6FDC8">      
2:     <StackPanel.Resources>      
3:         <c:String x:Key="strMessage">My String Value.</c:String>      
4:         <ImageBrush x:Key="imgBrush" ImageSource="Image/Users.png"      
5:                     ViewportUnits="Absolute" Viewport="0 0 32 32"/>      
6:     </StackPanel.Resources>      
7:     <TextBlock Margin="5" Text="Object Resource" />      
8:     <TextBox Margin="5" Text="{StaticResource strMessage}" />      
11:             Background="{StaticResource imgBrush}" Width="125" />      
12: </StackPanel>      

程式執行結果為:

WPF的靜态資源(StaticResource)和動态資源(DynamicResource)

連結位址: http://blog.csdn.net/tas/article/details/4259267