Какая разница между StaticResource и DynamicResource в WPF?

При использовании ресурсов, таких как кисти, шаблоны и стили в WPF, их можно указать либо как StaticResources

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

или как DynamicResource

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

В большинстве случаев (всегда?), только один работает, а другой будет генерировать исключение во время выполнения. Но я хотел бы знать, почему:

  • В чем основное отличие. Подобно последствиям памяти или производительности.
  • Существуют ли правила WPF, такие как "кисти всегда статичны" и "шаблоны всегда динамичны" и т.д.?

I предположим выбор между Static vs Dynamic не так произволен, как кажется... но я не вижу шаблон.

Ответ 1

A StaticResource будет разрешен и назначен этому свойству во время загрузки XAML, который возникает до того, как приложение действительно будет запущено. Он будет назначен только один раз, и любые изменения в словаре ресурсов игнорируются.

A DynamicResource назначает объект Expression свойству во время загрузки, но на самом деле не ищет ресурс до выполнения, когда объект Expression запрашивается для стоимость. Это откладывает поиск ресурса, пока он не понадобится во время выполнения. Хорошим примером может служить прямая ссылка на ресурс, определенный позже в XAML. Другим примером является ресурс, который даже не будет существовать до выполнения. Он обновит цель, если будет изменен словарь исходного ресурса.

Ответ 2

Я тоже был смущен. См. Этот пример ниже:

<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
  • И это тоже "до" они используются.

Надеюсь, я немного смутил.

Ответ 3

StaticResource будет разрешен при построении объекта.
DynamicResource будет оцениваться и решаться каждый раз, когда элементу управления нужен ресурс.

Ответ 4

Логические ресурсы позволяют вам определять объекты в XAML, которые не являются частью визуального дерева, но могут использоваться в вашем пользовательском интерфейсе. Одним из примеров логического ресурса является Brush, который используется для обеспечения цветовой схемы. Обычно эти объекты определяются как ресурсы, которые используются несколькими элементами приложений.

<Window.Resources>
    <RadialGradientBrush x:Key="myGradientBrush">
        <GradientStop Color="Green" Offset="0"/>
        <GradientStop Color="Blue" Offset="2"/>
    </RadialGradientBrush>
</Window.Resources>

Теперь выше объявленный ресурс может использоваться как статический или динамический ресурс. Следует помнить, что при использовании статических ресурсов он должен быть сначала определен в коде XAML, прежде чем его можно будет отнести. Статические и динамические ресурсы могут использоваться как:

<Grid Background="{StaticResource myGradientBrush}"></Grid>

или

<Grid Background="{DynamicResource myGradientBrush}"></Grid>

Разница между StaticResource и DynamicResource заключается в том, как ресурсы извлекаются элементами ссылки. StaticResource извлекаются только один раз ссылочным элементом и используются на протяжении всего ресурса ресурса. С другой стороны, DynamicResource приобретаются каждый раз, когда используется ссылочный объект.

Помещая это проще, если свойство цвета RadialGradientBrush изменяется в коде на оранжевый и розовый, тогда он будет отражать элементы только тогда, когда ресурс используется как DynamicResource. Ниже приведен код для изменения ресурса в коде:

RadialGradientBrush radialGradientBrush =
    new RadialGradientBrush(Colors.Orange, Colors.Pink);
this.Resources["myGradientBrush"] = radialGradientBrush;

Недостатком DynamicResource является то, что он снижает производительность приложения, поскольку ресурсы извлекаются каждый раз, когда они используются. Лучшей практикой является использование StaticResource, пока не будет определенной причины использовать DynamicResource.

Источник:
WPF: StaticResource и DynamicResource

Ответ 5

  • StaticResource использует первое значение. DynamicResource использует последнее значение.
  • DynamicResource может использоваться для вложенного стиля, StaticResource не может.

Предположим, что у вас есть этот вложенный словарь стиля. LightGreen находится на корневом уровне, а Pink - внутри Grid.

<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 как розовую, как она отображает сетку.

StaticResource StaticResource

DynamicResource DynamicResource

Имейте в виду, что VS Designer рассматривает DynamicResource как StaticResource. Он получит первое значение. В этом случае VS Designer отобразит кнопку LightGreen, хотя на самом деле она заканчивается как Pink.

StaticResource выдает ошибку при удалении стиля корневого уровня (LightGreen).

Ответ 6

В чем основное отличие. Как последствия памяти или производительности

Разница между статическими и динамическими ресурсами возникает при изменении базового объекта. Если ваша Кисть, определенная в коллекции Ресурсов, была доступна в коде и настроена на другой экземпляр объекта, Rectangle не обнаружит это изменение.

Статические ресурсы извлекаются один раз путем ссылки на элемент и используются для ресурса ресурса. В то время как DynamicResources извлекаются каждый раз, когда они используются.

Недостатком динамических ресурсов является снижение производительности приложений.

Существуют ли правила WPF, такие как "кисти всегда статичны" и "шаблоны всегда динамичны" и т.д.?

Лучшей практикой является использование статических ресурсов, если нет конкретной причины, по которой вы хотите динамически изменять ресурс в динамическом коде. Другим примером примера, в котором вы хотели бы использовать динамические резорбции, является использование SystemBrushes, SystenFonts и системных параметров.

Ответ 7

Нашел все ответы полезными, просто хотел добавить еще один вариант использования.

В составном сценарии WPF ваш пользовательский элемент управления может использовать ресурсы, определенные в любом другом родительском окне/элементе управления (который будет размещать этот пользовательский элемент управления), ссылаясь на этот ресурс как на DynamicResource.

Как упоминалось другими, Staticresource будет проверяться во время компиляции. Элементы управления пользователя не могут ссылаться на те ресурсы, которые определены в хостинге/родительском контроле. Хотя в этом случае можно использовать DynamicResource.

Ответ 8

Важное преимущество динамических ресурсов

если запуск приложения занимает очень много времени, вы должны использовать динамические ресурсы, потому что статические ресурсы всегда загружаются при создании окна или приложения, а динамические ресурсы загружаются, когда они сначала используются.

Однако вы не увидите никакой выгоды, если ваш ресурс не будет чрезвычайно большим и комплекс.

Ответ 9

Разница между StaticResource и DynamicResource заключается в том, как ресурсы извлекаются элементами ссылки. StaticResource извлекаются только один раз ссылочным элементом и используются на протяжении всего ресурса ресурса. С другой стороны, DynamicResource приобретаются каждый раз, когда используется ссылочный объект.

Ответ 10

Ниже приведены основные различия между статическими и динамическими ресурсами:

  • Статический ресурс будет оценивать ресурс только один раз, пока динамический ресурс будет оцениваться каждый раз, когда потребуется ресурс.

2.Динамический ресурс имеет больше служебных накладных расходов, чем статические ресурсы, потому что он ищет ресурсы каждый раз, когда он запрашивает или нуждается.

Ресурс 3.Static быстрее, но для загрузки страницы или окна требуется меньше времени, чем динамический ресурс, потому что динамические ресурсы загружаются, когда вы их используете.

Ответ 11

Динамические ресурсы могут использоваться только тогда, когда устанавливаемое свойство находится на объекте, который получен из объекта зависимостей или замораживается, где статические ресурсы могут использоваться где угодно. Вы можете абстрагировать весь элемент управления, используя статические ресурсы.

Статические ресурсы используются при следующих обстоятельствах:

       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.

Ответ 12

Статические ресурсы оценивают ресурс только один раз, а после этого, если ресурсы меняются, эти изменения не отражаются в привязке. Хотя динамические связанные ресурсы оцениваются каждый раз, когда ресурс необходим.