В чем разница между StaticResource и DynamicResource в WPF?

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

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

или как DynamicResource

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

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

  • В чем главное отличие. Как последствия для памяти или производительности
  • Есть ли в WPF правила вроде «кисти всегда статичны», «шаблоны всегда динамические» и т. д.?

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

Важно отметить, что разработчики приложений для Windows 8 не имеют DyanmicResource в качестве опции, только StaticResource.

Jerry Nixon 09.01.2013 00:43

@Jerry Nixon Слава богу, я сбился со счета, сколько раз мне не удавалось заставить что-либо работать, потому что я использовал DynamicResource вместо StaticResource или наоборот. С точки зрения программистов, это ненужная сложность. Аналогия - определения переменных. Должен ли я явно указывать, находится ли он в куче или стеке? И если я ошибаюсь, возникает катастрофическая ошибка времени выполнения?

Contango 22.09.2014 18:58

Для более подробного объяснения StaticResource и DynamicResource, а также когда их использовать, см. msdn.microsoft.com/en-us/library/ms750613%28v=vs.100%29.aspx‌.

Michael Repucci 22.09.2015 22:23
Стоит ли изучать PHP в 2026-2027 годах?
Стоит ли изучать PHP в 2026-2027 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Приемы CSS-макетирования - floats и Flexbox
Приемы CSS-макетирования - floats и Flexbox
Здравствуйте, друзья-студенты! Готовы совершенствовать свои навыки веб-дизайна? Сегодня в нашем путешествии мы рассмотрим приемы CSS-верстки - в...
Тестирование функциональных ngrx-эффектов в Angular 16 с помощью Jest
В системе управления состояниями ngrx, совместимой с Angular 16, появились функциональные эффекты. Это здорово и делает код определенно легче для...
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
491
3
183 792
8
Перейти к ответу Данный вопрос помечен как решенный

Ответы 8

Ответ принят как подходящий

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

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

Что нужно изменить, прежде чем мне понадобится DynamicResource? Возьмем, к примеру, шаблон: я определяю его один раз, но тогда, конечно, триггеры и прочее могут изменить содержимое шаблона, но шаблон остается тем же. Подойдет ли StaticResource здесь?

Isak Savo 14.10.2008 16:21

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

Phil Wright 14.10.2008 16:24

применима ли двухсторонняя привязка к обоим из них, если да, то какая будет разница в этом случае?

WhoIsNinja 30.12.2010 01:24

Последнее предложение действительно важно: It will update the target if the source resource dictionary is changed.

MEMark 16.12.2013 21:51

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

Gusdor 20.01.2015 16:25

Таким образом, StaticResource подобен константе, а DynamicResource подобен переменной.

Ryan Lundy 13.09.2016 17:27

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
  • И это тоже «до» их использования.

Надеюсь, я прояснил некоторую путаницу.

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

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

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

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

Есть ли в WPF правила вроде «кисти всегда статичны», «шаблоны всегда динамические» и т. д.?

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

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

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

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

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

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

Однако вы не увидите никакой выгоды, если ваш ресурс не слишком велик и сложный.

Для DynamicResources это создает проблему с производительностью только один раз (используется впервые) или каждый раз, когда используется элемент?

Morgane 26.05.2015 02:09

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

zamoldar 04.07.2017 01:58
  1. StaticResource использует значение первый. DynamicResource использует значение последний.
  2. DynamicResource можно использовать для вложенных стилей, StaticResource - нет.

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

<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, хотя на самом деле она будет розовой.

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

Все еще сбивает с толку, как LightGreen находится первым в словаре ресурсов, потому что Pink объявляется первым (как еще один выше). Я предполагаю, что когда xaml ищет стиль, он сначала соответствует «невложенному». Однако было бы полезно краткое объяснение.

ChocapicSz 06.11.2020 23:50

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

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

  1. При изменении ресурса реакции во время выполнения не требуется.
  2. Если вам нужна хорошая производительность с большим количеством ресурсов.
  3. При ссылке на ресурсы в одном словаре.

Динамические ресурсы:

  1. Значение свойства или темы установки стиля неизвестно до времени выполнения
    • Это включает в себя систему, приложение, настройки на основе темы
    • Это также включает прямые ссылки.
  2. Ссылка на большие ресурсы, которые могут не загружаться при загрузке страницы, окон, пользовательского управления.
  3. Ссылка на стили темы в настраиваемом элементе управления.

Другие вопросы по теме