WPF'de StaticResource ve DynamicResource arasındaki fark nedir?


474

WPF'de fırçalar, şablonlar ve stiller gibi kaynakları kullanırken, bunlar StaticResources olarak belirtilebilir

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

veya DynamicResource olarak

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

Çoğu zaman (her zaman?), Sadece biri çalışır ve diğeri çalışma zamanı sırasında istisna atar. Ama nedenini bilmek istiyorum:

  • Temel fark nedir. Bellek veya performans sonuçları gibi
  • WPF'de "fırçalar her zaman statik" ve "şablonlar her zaman dinamik" vb. Gibi kurallar var mı?

Ben varsayalım göründüğü gibi Dinamik vs Statik arasındaki seçim İsteğe bağlı olmak gibi olmadığı ... ama desen görmek için başarısız.


27
Windows 8 App geliştiricilerinin bir seçenek olarak DyanmicResource'a değil, sadece StaticResource'a sahip olduklarını unutmayın.
Jerry Nixon

2
@Jerry Nixon Bunun için şükürler olsun ki, StaticResource yerine DynamicResource kullandığım için işe hiçbir şey alamadığım sayımı kaybettim ya da tam tersi. Programcılar açısından bu gereksiz bir karmaşıklıktır. Bir benzetme değişken tanımlarıdır, açıkça yığın üzerinde mi yoksa yığınta mı yaşadığını belirtmem gerekir mi? Ve eğer yanlış anlarsam felaket bir çalışma zamanı hatası atar?
Contango

StaticResource ve DynamicResource'un daha ayrıntılı bir açıklaması ve her birinin ne zaman kullanılacağı için bkz. Msdn.microsoft.com/en-us/library/ms750613%28v=vs.100%29.aspx .
Michael Repucci

Yanıtlar:


466

Bir StaticResource çözüldü ve uygulama aslında çalıştırılan önce gerçekleşir XAML yükleme sırasında özelliğine atanır. Yalnızca bir kez atanır ve kaynak sözlüğünde yapılan değişiklikler göz ardı edilir.

Bir DynamicResource yükleme sırasında özelliğine bir Expression nesnesi atar ama İfade nesne değeri için sorulduğunda aslında çalışma zamanı kadar kaynak arama etmez. Bu, çalışma zamanında gerekinceye kadar kaynağı aramayı defers. Bunun iyi bir örneği, daha sonra XAML'de tanımlanan bir kaynağa yönelik ileri bir referans olabilir. Başka bir örnek, çalışma zamanına kadar var olmayacak bir kaynaktır. Kaynak kaynak sözlüğü değiştirilirse hedef güncellenir.


4
DynamicResource'u kullanmadan önce neleri değiştirmek zorundayım? Örneğin bir şablon alın: i bir kez tanımlayın, ancak elbette tetikleyiciler ve şeyler şablonun içeriğini değiştirebilir, ancak şablon hala aynıdır. StaticResource burada yapar mı?
Isak Savo

5
Bağlandığınız kaynak kullanım noktasından önce XAML'de tanımlanmışsa ve çalışan uygulamanın ömrü boyunca değişmeyecekse, StaticResource'u kullanın. Bu durumda StaticResource ile daha iyi performans elde edersiniz.
Phil Wright

4
twoWay bağlayıcı her ikisine de uygulanabilir mi, evet ise bu durumda fark ne olur?
WhoIsNinja

11
Son cümle gerçekten önemli:It will update the target if the source resource dictionary is changed.
MEMark

4
@IsakSavo Renk temalarına sahip bir kullanıcı arayüzü düşünün, Dinamik bir kaynakla, bir sözlüğü diğeriyle değiştirebilirsiniz ve yeni sözlükteki kaynaklara referans veren her şey otomatik olarak güncellenir.
Ocak'ta Gusdor

119

Onlar hakkında da kafam karıştı. Aşağıdaki bu örneğe bakın:

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

Burada düğme ve pencere için dinamik kaynak kullandım ve hiçbir yerde ilan etmedim.Çalışma zamanında, hiyerarşinin ResourceDictionary kontrol edilecektir.

Button'ı tıklatmak için aşağıdaki kodu eklerseniz, DynamicResource kullandıklarından, arka plan buna göre güncellenir.

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

StaticResource kullanmışlarsa:

  • Kaynak XAML'de bildirilmelidir
  • Ve bu da “önce” kullanılır.

Umarım bazı karışıklıkları giderdim.


31

StaticResource nesne yapımında çözülecektir.
Denetimin kaynağa her ihtiyacı olduğunda DynamicResource değerlendirilir ve çözümlenir.


21
  1. StaticResource ilk değeri kullanır . DynamicResource son değeri kullanır .
  2. DynamicResource iç içe stil için kullanılabilir, StaticResource kullanılamaz.

Bu iç içe Stil sözlüğünüz olduğunu varsayalım. LightGreen, Pembe bir Izgara içinde iç içe geçerken kök düzeyindedir.

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

Görünümünde:

<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, düğmeyi stilde bulduğu ilk değer olan LightGreen olarak görüntüler. DynamicResource, Izgarayı oluştururken LightGreen düğmesini Pembe olarak geçersiz kılar.

StaticResource StaticResource

DynamicResource DynamicResource

VS Designer'ın DynamicResource'a StaticResource olarak davrandığını unutmayın. İlk değeri alacaktır. Bu durumda, VS Designer, aslında Pembe olarak sonlanmasına rağmen düğmeyi LightGreen olarak görüntüler.

Kök seviyesi stili (LightGreen) kaldırıldığında StaticResource hata verir.


13

Temel fark nedir. Bellek veya performans sonuçları gibi

Statik ve dinamik kaynaklar arasındaki fark, temeldeki nesne değiştiğinde gelir. Kaynak koleksiyonunda tanımlanan Fırçanıza kodda erişilip farklı bir nesne örneğine ayarlanmışsa, Dikdörtgen bu değişikliği algılamaz.

Statik Kaynaklar, referans elemanı tarafından bir kez alınır ve kaynakların ömrü boyunca kullanılır. Oysa DynamicResources her kullanıldıklarında alır.

Dinamik kaynakların dezavantajı, uygulama performansını düşürme eğilimindedir.

WPF'de "fırçalar her zaman statik" ve "şablonlar her zaman dinamik" vb. Gibi kurallar var mı?

En iyi uygulama, arkasındaki koddaki kaynağı dinamik olarak değiştirmek istemediğiniz belirli bir neden olmadığı sürece Statik Kaynakları kullanmaktır. Dinamik kaynakların kullanılmasını istemediğiniz başka bir örnek, SystemBrushes, SystenFonts ve System Parameters'ı kullandığınızda verilebilir.


7

Tüm cevapları yararlı buldum, sadece bir kullanım durumu daha eklemek istedim.

Bileşik bir WPF senaryosunda, kullanıcı denetiminiz, bu kaynağa DynamicResource olarak başvurarak başka bir üst pencerede / denetimde (bu kullanıcı denetimini barındıracak) tanımlanan kaynakları kullanabilir.

Başkaları tarafından belirtildiği gibi, Staticresource derleme zamanında aranacaktır. Kullanıcı denetimleri, barındırma / üst denetimde tanımlanan kaynaklara başvuramaz. Yine de, bu durumda DynamicResource kullanılabilir.


3

Dinamik kaynakların önemli faydaları

uygulama başlangıcı çok uzun zaman alıyorsa, dinamik kaynaklar kullanmanız gerekir, çünkü pencere veya uygulama oluşturulduğunda statik kaynaklar her zaman yüklenirken, dinamik kaynaklar ilk kullanıldığında yüklenir.

Ancak, kaynağınız çok büyük ve karmaşık olmadıkça hiçbir fayda görmezsiniz.


DynamicResources için, yalnızca bir kez (ilk kez kullanılır) bir performans sorunu mu oluşturuyor yoksa öğe her kullanıldığında mı?
Morgane

bu durumda en çok kullanılan alanlar statik kaynak olmalı, özel kullanılan alanlar dinamik olabilir, yani ana pencere kaynakları için statik ve iletişim penceresi kaynağı dinamik olabilir
zamoldar

2

Dinamik kaynaklar yalnızca, ayarlanan özellik bağımlılık nesnesinden türetilen veya sabit kaynakların herhangi bir yerde kullanılabileceği şekilde donatılabilen nesnede olduğunda kullanılabilir. Statik kaynakları kullanarak tüm kontrolü soyutlayabilirsiniz.

Statik kaynaklar aşağıdaki koşullar altında kullanılır:

  1. Reaksiyon kaynağı çalışma zamanında değiştiğinde gerekli değildir.
  2. Çok sayıda kaynakla iyi bir performansa ihtiyacınız varsa.
  3. Aynı sözlük içindeki kaynaklara başvururken.

Dinamik kaynaklar:

  1. Özellik veya stil ayarlayıcı temasının değeri çalışma zamanına kadar bilinmiyor
    • Bu sistem, uygulama, tema tabanlı ayarları içerir
    • Bu, ileri referansları da içerir.
  2. Sayfa, pencere, kullanıcı kontrolü yüklendiğinde yüklenemeyen büyük kaynaklara başvurma.
  3. Özel bir denetimde tema stillerine başvurma.
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.