Вопрос

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

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

или как DynamicResource

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

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

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

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

Это было полезно?

Решение

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

А ДинамическийРесурс присваивает объект Expression свойству во время загрузки, но фактически не ищет ресурс до тех пор, пока во время выполнения у объекта Expression не будет запрошено значение.Это откладывает поиск ресурса до тех пор, пока он не понадобится во время выполнения.Хорошим примером может быть прямая ссылка на ресурс, определенный позже в 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 иерархии. Поскольку я его не определил, я предполагаю, что будет использоваться значение по умолчанию.

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

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

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

или:

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

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

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

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

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

Источник:
ВПФ:СтатикРесурс против.ДинамическийРесурс

  1. StaticResource использует первый ценить.DynamicResource использует последний ценить.
  2. 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 на Pink при отрисовке сетки.

StaticResourceСтатикРесурс

DynamicResourceДинамическийРесурс

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

  1. Значение свойства или темы установки стиля неизвестно до времени выполнения.
    • Сюда входят настройки системы, приложения и темы.
    • Сюда также входят ссылки вперед.
  2. Ссылка на большие ресурсы, которые могут не загружаться при загрузке страницы, окон и пользовательского элемента управления.
  3. Ссылка на стили темы в пользовательском элементе управления.
Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top