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

原文: 靜態資源(StaticResource)和動態資源(DynamicResource)

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

資源能夠做爲靜態資源或動態資源進行引用。這是經過使用 StaticResource 標記擴展或 DynamicResource 標記擴展完成的。css

      StaticResource 經過替換已定義資源的值來爲 XAML 屬性提供值。html

      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>
   8:     
   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: }

以上的例子在運行時顯示以下:ui

StaticAndDynamicResourceA

而點擊「Change Button Resource」按鈕後,顯示的結果爲:this

StaticAndDynamicResourceB

從程序執行的結果來看,咱們能夠獲得以下的結論:spa

  • 靜態資源引用是從控件所在的容器開始依次向上查找的,而動態資源的引用是從控件開始向上查找的(即控件的資源覆蓋其父容器的同名資源)
  • 更改資源時,動態引用的控件樣式發生變化(即"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;

執行的結果以下:.net

StaticAndDynamicResourceC

 

靜態資源引用最適合於如下狀況:設計

  • 您的應用程序設計幾乎將全部的應用程序資源集中到頁或應用程序級別的資源字典中。靜態資源引用不會基於運行時行爲(例如從新加載頁)進行從新求值,所以,根據您的資源和應用程序設計避免大量沒必要要的動態資源引用,這樣能夠提升性能。

  • 您正在設置不在 DependencyObject 或 Freezable 上的屬性的值。

  • 您正在建立將編譯爲 DLL 並打包爲應用程序的一部分或在應用程序之間共享的資源字典。

  • 您正在爲自定義控件建立一個主題,並定義在主題中使用的資源。對於這種狀況,一般不須要動態資源引用查找行爲,而須要靜態資源引用行爲,以使該查找可預測而且獨立於該主題。使用動態資源引用時,即便是主題中的引用也會直到運行時才進行求值,而且在應用主題時,某個本地元素有可能會從新定義您的主題試圖引用的鍵,而且本地元素在查找中會位於主題自己以前。若是發生該狀況,主題將不會按預期方式運行。

  • 您正在使用資源來設置大量依賴項屬性。依賴項屬性具備由屬性系統啓用的有效值緩存功能,所以,若是您爲能夠在加載時求值的依賴項屬性提供值,該依賴項屬性將沒必要查看從新求值的表達式,而且能夠返回最後一個有效值。該方法具備性能優點。

  • 您須要爲全部使用者更改基礎資源,或者須要經過使用 x:Shared 屬性爲每一個使用者維護獨立的可寫實例。

動態資源最適合於如下狀況:

  • 資源的值取決於直到運行時才知道的狀況。這包括系統資源,或用戶可設置的資源。例如,您能夠建立引用由 SystemColors、SystemFonts 或 SystemParameters 公開的系統屬性的 setter 值。這些值是真正動態的,由於它們最終來自於用戶和操做系統的運行時環境。您還可使用能夠更改的應用程序級別的主題,在此狀況下,頁級別的資源訪問還必須捕獲更改。

  • 您正在爲自定義控件建立或引用主題樣式。

  • 您但願在應用程序生存期調整 ResourceDictionary 的內容。

  • 您有一個存在依存關係的複雜資源結構,在這種狀況下,可能須要前向引用。靜態資源引用不支持前向引用,但動態資源引用支持,由於資源直到運行時才須要進行求值,所以,前向引用不是一個相關概念。

  • 從編譯或工做集角度來講,您引用的資源特別大,而且加載頁時可能沒法當即使用該資源。靜態資源引用始終在加載頁時從 XAML 加載;而動態資源引用直到實際使用時纔會加載。

  • 您要建立的樣式的 setter 值可能來自受主題或其餘用戶設置影響的其餘值。

  • 您正在將資源應用到元素,而在應用程序生存期中可能會在邏輯樹中從新設置該元素的父級。更改此父級還可能會更改資源查找範圍,所以,若是您但願基於新範圍對從新設置了父級的元素的資源進行從新求值,請始終使用動態資源引用。

不一樣類型的資源

一、程序集資源。這種常見於將圖片設定到程序集中,作爲程序集的資源。

程序集資源在定義時,將文件複製到解決方案-項目所在的目錄或其子目錄中,並將文件的屬性中的Build Action設置爲Resource。(注意,WPF不支持項目屬性中的資源)

AssemblyResource

 

 

 

 

 

 

而後在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中將封裝該圖片文件。此種方法適用於較小的資源。

二、對象資源

除剛剛咱們使用的圖片作爲程序集資源外,前面例子中所使用的資源均是對象資源。系統對於對象資源使用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}" />
   9:     <Button Margin="5" Height="32" HorizontalContentAlignment="Right" 
  10:             Content="{StaticResource strMessage}" 
  11:             Background="{StaticResource imgBrush}" Width="125" />
  12: </StackPanel>

 

程序執行結果爲:

AsmAndObjResource

相關文章
相關標籤/搜索