.net resourcedictionary - StaticResource和WPF中的DynamicResource有什麼區別?




xaml resources (11)

以下是靜態和動態資源的主要區別:

  1. 靜態資源只會評估一次資源,而每次資源需要時都會評估動態資源。

2.動態資源比靜態資源具有更多的性能開銷,因為它每次請求或需要時都會查找資源。

3.靜態資源速度更快,但加載頁面或窗口所需的時間比動態資源更少,因為實際使用動態資源時會加載動態資源。

在WPF中使用資源(如畫筆,模板和样式)時,可以將它們指定為StaticResources

<Rectangle Fill="{StaticResource MyBrush}" />

或者作為一個DynamicResource

<ItemsControl ItemTemplate="{DynamicResource MyItemTemplate}"  />

大部分時間(總是?),只有一個有效,另一個會在運行時拋出異常。 但我想知道為什麼:

  • 主要區別是什麼? 像內存或性能影響
  • WPF中有像“畫筆總是靜態的”和“模板總是動態的”等規則嗎?

認為靜態與動態之間的選擇並不像看起來那麼武斷......但我看不到這種模式。


主要區別是什麼? 像內存或性能影響

當底層對象發生變化時,靜態資源和動態資源的區別就在於此。 如果在資源集合中定義的Brush在代碼中訪問並設置為不同的對象實例,則Rectangle不會檢測到此更改。

靜態資源通過引用元素檢索一次,並用於資源的生命週期。 而DynamicResources在每次使用時都會檢索。

動態資源的缺點是它們傾向於降低應用程序的性能。

WPF中有像“畫筆總是靜態的”和“模板總是動態的”等規則嗎?

最好的做法是使用靜態資源,除非有特定的原因,比如你想動態改變代碼中的資源。 您希望使用動態資源的另一個示例包括使用SystemBrushes,SystenFonts和System Parameters時的情況。


StaticResource將在對象構造上解析。
每當控制需要資源時,DynamicResource將被評估和解決。


我也對他們感到困惑。 看下面這個例子:

<Window x:Class="WpfApplicationWPF.CommandsWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        Title="CommandsWindow" Height="300" Width="300">

    <StackPanel>
        <Button Name="ButtonNew" 
                Click="ButtonNew_Click" 
                Background="{DynamicResource PinkBrush}">NEW</Button>
        <Image Name="ImageNew" 
               Source="pack://application:,,,/images/winter.jpg"></Image>
    </StackPanel>


    <Window.Background>
        <DynamicResource ResourceKey="PinkBrush"></DynamicResource>
    </Window.Background>

</Window>

在這裡,我使用了按鈕和窗口的動態資源,並沒有在任何地方聲明它。在運行時,層次結構的ResourceDictionary將被檢查。由於我沒有定義它,所以我猜默認值會被使用。

如果我添加下面的代碼來點擊Button的事件,因為他們使用DynamicResource,所以後台會相應地更新。

private void ButtonNew_Click(object sender, RoutedEventArgs e)
{
    this.Resources.Add(  "PinkBrush"
                         ,new SolidColorBrush(SystemColors.DesktopColor)
                       );
}

如果他們使用了StaticResource:

  • 資源必須在XAML中聲明
  • 這也是“之前”他們使用。

希望我澄清了一些混淆。


動態資源只有在被設置的屬性位於從依賴對象派生的對像上時才能使用,或者可以在任何地方使用靜態資源的情況下使用。 您可以使用靜態資源抽像出整個控件。

在以下情況下使用靜態資源:

       1.When reaction resource changes at runtime is not required.
       2.If you need a good performance with lots of resources.
       3.While referencing resources within the same dictionary.

 Dynamic resources:
   1.Value of property or style setter theme is not known untill runtime 
      a. This include system ,aplication,theme based settings
      b. This also includes forward references.

   2.Referencing large resources that may not load when    page,windows,usercontrol loads .

   3. Referncing theme styles in a custom control.

StaticResource和DynamicResource的區別在於資源是如何被引用元素檢索的。 StaticResource只被引用元素檢索一次,並用於資源的整個生命週期。 另一方面,每次使用引用對象時都會獲取DynamicResource。


靜態引用資源僅對資源進行一次評估,如果資源發生更改,則這些更改不會反映在綁定中。 每次需要資源時都會評估動態引用資源。


找到所有有用的答案,只是想增加一個用例。

在復合WPF場景中,您的用戶控件可以通過將該資源作為DynamicResource引用來使用任何其他父窗口/控件(即將託管此用戶控件)中定義的資源。

正如其他人所提到的,Staticresource將在編譯時查詢。 用戶控件無法引用在宿主/父級控制中定義的資源。 雖然在這種情況下可以使用DynamicResource。


在加載實際運行應用程序之前發生的XAML期間, StaticResource將被解析並分配給屬性。 它只會被分配一次,並且任何對資源字典的更改都會被忽略。

DynamicResource在加載過程中將一個Expression對象分配給該屬性,但在Expression對像被要求輸入值時才直接在運行時查找該資源。 這延遲查找資源,直到它在運行時需要。 一個很好的例子就是對後面在XAML中定義的資源的前向引用。 另一個例子是直到運行時才會存在的資源。 如果源資源字典發生更改,它將更新目標。


  1. StaticResource使用第一個值。 DynamicResource使用最後一個值。
  2. DynamicResource可以用於嵌套樣式,StaticResource不能。

假設你有這個嵌套的Style字典。 LightGreen位於根層,Pink則嵌套在網格內。

<ResourceDictionary xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
                    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">
    <Style TargetType="{x:Type Grid}">
        <Style.Resources>
            <Style TargetType="{x:Type Button}" x:Key="ConflictButton">
                <Setter Property="Background" Value="Pink"/>
            </Style>
        </Style.Resources>
    </Style>
    <Style TargetType="{x:Type Button}" x:Key="ConflictButton">
        <Setter Property="Background" Value="LightGreen"/>
    </Style>
</ResourceDictionary>

鑑於:

<Window x:Class="WpfStyleDemo.ConflictingStyleWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        Title="ConflictingStyleWindow" Height="100" Width="100">
    <Window.Resources>
        <ResourceDictionary>
            <ResourceDictionary.MergedDictionaries>
                <ResourceDictionary Source="Styles/ConflictingStyle.xaml" />
            </ResourceDictionary.MergedDictionaries>
        </ResourceDictionary>
    </Window.Resources>
    <Grid>
        <Button Style="{DynamicResource ConflictButton}" Content="Test"/>
    </Grid>
</Window>

StaticResource會將按鈕渲染為LightGreen,這是它在樣式中找到的第一個值。 DynamicResource會在呈現網格時將LightGreen按鈕替代為Pink。

靜態資源

DynamicResource

請記住,VS Designer將DynamicResource視為StaticResource。 它會獲得第一價值。 在這種情況下,VS Designer會將該按鈕渲染為LightGreen,儘管它實際上最終為Pink。

當根級別樣式(LightGreen)被移除時,StaticResource會引發錯誤。


string是保留字,但String只是一個類名。 這意味著string本身不能用作變量名。

如果由於某種原因你想要一個名為string的變量,你只會看到第一個這樣的編譯:

StringBuilder String = new StringBuilder();  // compiles
StringBuilder string = new StringBuilder();  // doesn't compile 

如果你真的想要一個名為string的變量名,你可以使用@作為前綴:

StringBuilder @string = new StringBuilder();

另一個重要區別:以不同的方式強調它們。





.net wpf xaml resources