Jaka jest różnica między StaticResource i DynamicResource w WPF?

Podczas korzystania z zasobów, takich jak pędzle, szablony i style w WPF, mogą one być określone jako StaticResources

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

Lub jako DynamicResource

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

Najczęściej (zawsze?), tylko jeden działa, a drugi wyrzuci wyjątek podczas wykonywania. Ale chciałbym wiedzieć dlaczego:

  • Jaka jest główna różnica. Jak pamięć lub wydajność implikacje
  • czy w WPF istnieją reguły takie jak "pędzle są zawsze statyczne" i " szablony są zawsze dynamiczne " itp.?

I zakładam Wybór pomiędzy statycznym a dynamicznym nie jest tak arbitralny, jak się wydaje... ale nie widzę wzoru.

Author: brian d foy, 2008-10-14

8 answers

A StaticResource zostanie rozwiązane i przypisane do właściwości podczas ładowania XAML, które nastąpi przed uruchomieniem aplikacji. Zostanie on przypisany tylko raz, a wszelkie zmiany w słowniku zasobów zostaną zignorowane.

A DynamicResource przypisuje właściwość Expression obiekt podczas ładowania, ale w rzeczywistości nie wyszukuje zasobu do czasu uruchomienia, gdy obiekt Expression jest pytany o wartość. Opóźnia to przeglądanie zasobu, dopóki nie zostanie potrzebne w czasie wykonywania. Dobrym przykładem może być odniesienie do zasobu zdefiniowanego później w XAML. Innym przykładem jest zasób, który nie będzie istniał do czasu uruchomienia. Zaktualizuje cel, jeśli słownik zasobów źródłowych zostanie zmieniony.

 481
Author: Phil Wright,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2015-11-10 08:47:51

Ja też byłem zdezorientowany. Zobacz poniższy przykład:

<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>

Tutaj użyłem dynamicznego zasobu dla przycisku i okna i nie zadeklarowałem go nigdzie.Po uruchomieniu zostanie sprawdzony ResourceDictionary hierarchii.Ponieważ nie zdefiniowałem go, domyślam się, że zostanie użyta wartość domyślna.

Jeśli dodam poniższy kod, aby kliknąć Zdarzenie przycisku, ponieważ używają DynamicResource, tło zostanie odpowiednio zaktualizowane.

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

Gdyby użyli StaticResource:

  • zasób musi być zadeklarowany w XAML
  • i że zbyt "przed" są one używane.
Mam nadzieję, że oczyściłem trochę zamieszania.
 122
Author: Akshay J,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2013-04-22 03:25:45

StaticResource zostanie rozwiązane podczas budowy obiektu.
DynamicResource będzie oceniane i rozwiązywane za każdym razem, gdy kontrola potrzebuje zasobu.

 34
Author: Afshin,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2010-12-26 02:23:33
  1. StaticResource używa pierwszej wartości. DynamicResource używa wartości last .
  2. DynamicResource może być używany do stylizacji zagnieżdżonej, StaticResource nie może.

Załóżmy, że masz zagnieżdżony słownik stylów. LightGreen jest na poziomie głównym, podczas gdy Pink jest zagnieżdżony wewnątrz siatki.

<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>

W widoku:

<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 wyrenderuje przycisk jako LightGreen, pierwszą wartość, jaką znalazł w stylu. DynamicResource nadpisze LightGreen przycisk Tak Różowy, jak renderuje siatkę.

StaticResourceStaticResource

DynamicResourceDynamicResource

Należy pamiętać, że VS Designer traktuje DynamicResource jako StaticResource. Otrzyma pierwszą wartość. W tym przypadku VS Designer renderuje przycisk jako LightGreen, chociaż w rzeczywistości kończy się jako różowy.

StaticResource wyświetli błąd, gdy Styl na poziomie głównym (LightGreen) zostanie usunięty.

 26
Author: Jeson Martajaya,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2015-04-27 18:19:41

Jaka jest główna różnica. Jak implikacje pamięci lub wydajności

Różnica między statycznymi i dynamicznymi zasobami pojawia się, gdy zmienia się obiekt bazowy. Jeśli Pędzel zdefiniowany w kolekcji zasobów był dostępny w kodzie i ustawiony na inną instancję obiektu, Rectangle nie wykryje tej zmiany.

Zasoby statyczne pobierane jednorazowo przez odniesienie do elementu i używane przez cały okres eksploatacji zasobów. Natomiast DynamicResources odzyskać za każdym razem są używane.

Wadą zasobów dynamicznych jest to, że mają tendencję do zmniejszania wydajności aplikacji.

Czy w WPF istnieją reguły takie jak "pędzle są zawsze statyczne" i "szablony są zawsze dynamiczne" itp.?

Najlepszą praktyką jest używanie zasobów statycznych, chyba że istnieje konkretny powód, dla którego chcesz zmienić zasoby w kodzie za dynamicznie. Innym przykładem przykładu, w którym chcesz t używać dynamicznych resoruces obejmują, gdy używasz Systemowe, systemowe i parametry systemu.

 14
Author: CharithJ,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2013-03-30 01:58:28

Wszystkie odpowiedzi okazały się przydatne, chciałem tylko dodać jeszcze jeden przypadek użycia.

W złożonym scenariuszu WPF, kontrola użytkownika może korzystać z zasobów zdefiniowanych w dowolnym innym oknie nadrzędnym / kontroli (która będzie hostować tę kontrolę użytkownika), odnosząc się do tego zasobu jako DynamicResource.

Jak wspomnieli inni, Staticresource zostanie sprawdzony podczas kompilacji. Kontrolki użytkownika nie mogą odnosić się do tych zasobów, które są zdefiniowane w kontroli hosting/rodzic. Jednak DynamicResource może być stosowane w tym przypadku.

 8
Author: Manish Basantani,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2014-01-24 10:01:15

Ważna korzyść z dynamicznych zasobów

Jeśli uruchomienie aplikacji zajmuje bardzo dużo czasu, musisz użyć dynamicznych zasobów, ponieważ zasoby statyczne są zawsze ładowane podczas tworzenia okna lub aplikacji, podczas gdy zasoby dynamiczne są ładowane, gdy są używane po raz pierwszy.

Jednak nie zobaczysz żadnych korzyści, chyba że Twoje zasoby są bardzo duże i złożone.

 3
Author: zamoldar,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2014-11-28 22:05:08

Zasoby dynamiczne mogą być używane tylko wtedy, gdy właściwość ustawiana jest na obiekcie, który jest pochodną obiektu zależności lub freezable, gdzie jako zasoby statyczne mogą być używane w dowolnym miejscu. Możesz wyodrębnić całą kontrolę za pomocą zasobów statycznych.

Zasoby statyczne są wykorzystywane w następujących okolicznościach:

  1. gdy zmiana zasobów reakcji w czasie wykonywania nie jest wymagana.
  2. jeśli potrzebujesz dobrej wydajności z dużą ilością zasobów.
  3. While odwoływanie się do zasobów w tym samym słowniku.

Zasoby dynamiczne:

  1. wartość właściwości lub motywu ustawiacza stylów nie jest znana do czasu uruchomienia
    • obejmują system, aplikację, Ustawienia oparte na temacie
    • obejmuje to również odniesienia do przyszłości.
  2. odwołuje się do dużych zasobów, które mogą nie ładować się, gdy ładuje się page, windows, usercontrol.
  3. odwoływanie się do stylów motywów w niestandardowej kontroli.
 2
Author: iaminvinicble,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2018-05-11 18:22:07