Яка різниця між StaticResource та DynamicResource у WPF?


473

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

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

або як DynamicResource

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

У більшості випадків (завжди?) Лише один працює, а інший буде кидати виняток під час виконання. Але я хотів би знати, чому:

  • У чому головна відмінність. Як і пам'ять, або продуктивність
  • Чи є у WPF такі правила, як "кисті завжди статичні" та "шаблони завжди динамічні" тощо?

Я припускаю, що вибір між Static vs Dynamic не такий довільний, як здається ... але я не бачу картини.


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

2
@ Джеррі Ніксон Дякую Богові за це, я втратила кількість разів, коли мені не вдалося щось працювати, тому що я використовував DynamicResource замість StaticResource або навпаки. З точки зору програмістів, це зайва складність. Аналогія - це мінливі визначення, чи повинен я чітко вказати, чи живе він у купі чи стеку? І якщо я помиляюсь, це кидає катастрофічну помилку виконання?
Контанго

Для більш ретельного пояснення StaticResource та DynamicResource та коли їх використовувати, див. Msdn.microsoft.com/en-us/library/ms750613%28v=vs.100%29.aspx .
Майкл Репуччі

Відповіді:


466

StaticResource буде вирішене , і привласнюється властивості під час завантаження XAML , яке відбувається до того , як додаток реально працювати. Він буде призначений лише один раз, а будь-які зміни в словнику ресурсів ігноруються.

DynamicResource привласнює об'єкт Expression властивості під час завантаження , але не на самому ділі не LookUp ресурсу до часу виконання , коли об'єкт Expression задаються для значення. Це відкладає пошук ресурсу, поки він не потрібен під час виконання. Хорошим прикладом може бути пряма посилання на ресурс, визначений пізніше в XAML. Ще один приклад - ресурс, який навіть не буде існувати до часу виконання. Він оновить ціль, якщо змінено словник вихідних ресурсів.


4
Що потрібно змінити, перш ніж мені потрібно використовувати DynamicResource? Наприклад, візьміть шаблон: я визначаю його один раз, але тоді, звичайно, тригери і речі можуть змінити вміст шаблону, але шаблон все одно той же. Чи зробив би тут StaticResource?
Ісак Саво

5
Використовуйте StaticResource, якщо ресурс, до якого ви приєднуєтесь, визначений у XAML перед його точкою використання та не збирається змінювати впродовж життя запущеної програми. У такому випадку ви отримуєте кращі показники роботи з StaticResource.
Філ Райт

4
чи застосовується двостороння обов'язковість для обох цих, якщо так, яка буде різниця в цьому випадку?
WhoIsNinja

11
Останнє речення дійсно важливе:It will update the target if the source resource dictionary is changed.
ПАМ'ЯТ

4
@IsakSavo Розгляньте інтерфейс користувача з кольоровими темами. За допомогою динамічного ресурсу ви можете поміняти один словник на інший, і все, що посилається на ресурси, у новому словнику оновиться автоматично.
Гусдор

119

Я також був розгублений щодо них. Дивіться цей приклад нижче:

<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
  • І це теж "раніше" вони використовуються.

Сподіваюся, я очистив деяку плутанину.


31

StaticResource буде вирішено щодо побудови об'єкта.
DynamicResource буде оцінюватися та вирішуватися кожен раз, коли ресурс потребує ресурсу.


21
  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 буде заміняти кнопку LightGreen як рожевий під час відображення сітки.

StaticResource StaticResource

DynamicResource DynamicResource

Майте на увазі, що VS Designer розглядає DynamicResource як StaticResource. Це отримає перше значення. У цьому випадку VS Designer видасть кнопку як LightGreen, хоча насправді вона закінчується як Pink.

StaticResource видасть помилку при видаленні стилю кореневого рівня (LightGreen).


13

У чому головна відмінність. Як і пам'ять, або продуктивність

Різниця між статичними та динамічними ресурсами виникає при зміні базового об'єкта. Якщо ваша кисть, визначена у колекції ресурсів, отримала доступ до коду та встановлена ​​для іншого екземпляра об'єкта, прямокутник не виявить цієї зміни.

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

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

Чи є у WPF такі правила, як "кисті завжди статичні" та "шаблони завжди динамічні" тощо?

Найкраща практика - це використовувати Статичні ресурси, якщо немає конкретної причини, як ви хочете динамічно змінювати ресурс у коді. Інший приклад, у якому ви хочете, щоб t використовував динамічні резорації, включають, коли ви використовуєте SystemBrushes, SystenFonts та System Parameters.


7

Знайшов усі відповіді корисними, просто хотів додати ще один випадок використання.

У складеному сценарії WPF ваше керування користувачем може використовувати ресурси, визначені в будь-якому іншому батьківському вікні / елементі управління (який буде розміщувати цей елемент управління), посилаючись на цей ресурс як на DynamicResource.

Як зазначають інші, Staticresource буде розглянуто під час компіляції. Керування користувачами не може посилатися на ті ресурси, які визначені в хостинговому / батьківському контролі. Хоча в цьому випадку може бути використаний DynamicResource.


3

Важлива перевага динамічних ресурсів

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

Однак ви не побачите жодної користі, якщо ваш ресурс надзвичайно великий і складний.


Що стосується DynamicResources, це створює питання про продуктивність лише один раз (використовується вперше) або це кожен раз, коли елемент використовується?
Morgane

у цьому випадку найбільш використовувані поля повинні бути статичним ресурсом, користувацькі поля можуть бути динамічними, тобто для ресурсів
основного

2

Динамічні ресурси можна використовувати лише тоді, коли властивість, що встановлюється, знаходиться на об'єкті, який походить від об'єкта залежності, або заморожується там, де статичні ресурси можуть використовуватися в будь-якому місці. Ви можете відмовитись від повного контролю за допомогою статичних ресурсів.

Статичні ресурси використовуються за таких обставин:

  1. Коли зміна ресурсу реакції під час виконання не потрібна.
  2. Якщо вам потрібна хороша робота з великою кількістю ресурсів.
  3. Посилаючись на ресурси в одному словнику.

Динамічні ресурси:

  1. Значення тематики властивостей чи стилів невідоме до моменту виконання
    • Сюди можна віднести налаштування на основі системи, програм, тем
    • Сюди також входять прямі посилання.
  2. Посилання на великі ресурси, які можуть не завантажуватися під час завантаження сторінки, windows, користувальницького контролю.
  3. Посилання на стилі тем у користувацькому керуванні.
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.