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

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

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

или как DynamicResource

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

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

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

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

12 ответов


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

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


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

<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 иерархии.Поскольку я не определил его, я думаю, что будет использоваться значение по умолчанию.

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

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

Если они использовали StaticResource:

  • ресурс должен быть объявлен в XAML
  • и это тоже "до" они используются.

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


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


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

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

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

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

или:

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

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

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

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

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

источник:
WPF: StaticResource против DynamicResource


  1. расширение StaticResource использует первый значение. Оператора DynamicResource использует последние значение.
  2. DynamicResource можно использовать для вложенного стиля, StaticResource не может.

Предположим, у вас есть этот вложенный словарь стилей. 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 переопределит светло-зеленую кнопку как розовую, поскольку она отображает сетку.

StaticResource Для StaticResource

DynamicResource Оператора DynamicResource

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

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


в чем основное отличие. Например, память или производительность

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

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

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

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

рекомендуется использовать статические ресурсы, если нет конкретной причины, как вы хотите изменить ресурс в коде позади динамически. Другой пример экземпляра, в котором вы хотите t использовать динамические resoruces включают, когда вы используете SystemBrushes, SystenFonts и системные параметры.


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

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

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


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

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

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


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


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

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

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

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


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

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

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

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

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

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