Apa perbedaan antara StaticResource dan DynamicResource di WPF?

474

Saat menggunakan sumber daya seperti kuas, templat, dan gaya di WPF, mereka dapat ditentukan sebagai StaticResources

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

atau sebagai DynamicResource

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

Sebagian besar waktu (selalu?), Hanya satu yang berfungsi dan yang lainnya akan melempar pengecualian selama runtime. Tapi saya ingin tahu mengapa:

  • Apa perbedaan utamanya? Suka ingatan atau implikasi kinerja
  • Apakah ada aturan di WPF seperti "kuas selalu statis" dan "templat selalu dinamis" dll.?

Saya menganggap pilihan antara Statis vs Dinamis tidak semena-mena seperti kelihatannya ... tapi saya gagal melihat polanya.

Isak Savo
sumber
27
Penting untuk dicatat bahwa pengembang Aplikasi Windows 8 tidak memiliki DyanmicResource sebagai opsi, hanya StaticResource.
Jerry Nixon
2
@ Jerry Nixon Terima kasih Tuhan untuk itu, saya telah kehilangan hitungan berapa kali saya tidak bisa mendapatkan apa pun untuk bekerja karena saya menggunakan DynamicResource bukan StaticResource, atau sebaliknya. Dari sudut pandang programmer, ini adalah kompleksitas yang tidak perlu. Analogi adalah definisi variabel, haruskah saya harus secara eksplisit menentukan apakah itu hidup di heap atau stack? Dan jika saya salah ia melemparkan kesalahan runtime bencana?
Contango
Untuk penjelasan lebih lengkap tentang StaticResource dan DynamicResource, dan kapan menggunakannya, lihat msdn.microsoft.com/en-us/library/ms750613%28v=vs.100%29.aspx .
Michael Repucci

Jawaban:

466

Sebuah StaticResource akan diselesaikan dan ditugaskan untuk properti selama pemuatan XAML yang terjadi sebelum aplikasi benar-benar menjalankan. Ini hanya akan diberikan satu kali dan perubahan pada kamus sumber daya diabaikan.

Sebuah DynamicResource memberikan sebuah objek Expression ke properti selama pemuatan tetapi tidak benar-benar lookup sumber daya sampai runtime ketika objek Ekspresi diminta untuk nilai. Ini menghalangi mencari sumber daya sampai dibutuhkan saat runtime. Contoh yang baik akan menjadi referensi maju ke sumber daya yang ditentukan kemudian di XAML. Contoh lain adalah sumber daya yang bahkan tidak akan ada sampai runtime. Ini akan memperbarui target jika kamus sumber daya diubah.

Phil Wright
sumber
4
Apa yang harus diubah sebelum saya perlu menggunakan DynamicResource? Ambil contoh template: saya mendefinisikannya sekali tetapi kemudian tentu saja pemicu dan hal-hal dapat mengubah konten template tetapi template masih sama. Apakah StaticResource lakukan di sini?
Isak Savo
5
Gunakan StaticResource jika sumber daya yang Anda lampirkan didefinisikan dalam XAML sebelum titik penggunaannya dan tidak akan berubah selama aplikasi berjalan. Dalam hal ini Anda mendapatkan kinerja yang lebih baik dengan StaticResource.
Phil Wright
4
apakah duaWay mengikat berlaku untuk keduanya, jika ya apa perbedaan dalam kasus itu?
WhoIsNinja
11
Kalimat terakhir sangat penting:It will update the target if the source resource dictionary is changed.
MEMark
4
@IsakSavo Pertimbangkan UI dengan tema warna, Dengan sumber daya yang dinamis, Anda dapat bertukar satu kamus dengan kamus lain dan sumber referensi apa pun dalam kamus baru akan diperbarui secara otomatis.
Gusdor
119

Saya juga bingung tentang mereka. Lihat contoh ini di bawah:

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

Di sini saya telah menggunakan sumber daya dinamis untuk tombol dan jendela dan belum menyatakannya di mana saja. Setelah runtime, ResourceDictionary dari hierarki akan diperiksa. Karena saya belum mendefinisikannya, saya kira default akan digunakan.

Jika saya menambahkan kode di bawah ini untuk mengklik acara Button, karena mereka menggunakan DynamicResource, latar belakang akan diperbarui.

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

Jika mereka menggunakan StaticResource:

  • Sumber daya harus dinyatakan dalam XAML
  • Dan itu juga "sebelum" mereka digunakan.

Saya harap saya membersihkan beberapa kebingungan.

Akshay J
sumber
31

StaticResource akan diselesaikan pada konstruksi objek.
DynamicResource akan dievaluasi dan diselesaikan setiap kali kontrol membutuhkan sumber daya.

Afshin
sumber
21
  1. StaticResource menggunakan nilai pertama . DynamicResource menggunakan nilai terakhir .
  2. DynamicResource dapat digunakan untuk penataan bersarang, StaticResource tidak dapat.

Misalkan Anda memiliki kamus Style bersarang ini. LightGreen berada di tingkat root sedangkan Pink bersarang di dalam 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>

Dalam penglihatan:

<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 akan merender tombol sebagai LightGreen, nilai pertama yang ditemukan dalam style. DynamicResource akan mengesampingkan tombol LightGreen sebagai Pink saat merender Grid.

StaticResource StaticResource

DynamicResource DynamicResource

Perlu diingat bahwa VS Designer memperlakukan DynamicResource sebagai StaticResource. Itu akan mendapatkan nilai pertama. Dalam hal ini, VS Designer akan membuat tombol sebagai LightGreen meskipun sebenarnya berakhir sebagai Pink.

StaticResource akan melempar kesalahan ketika gaya tingkat akar (LightGreen) dihapus.

Jeson Martajaya
sumber
13

Apa perbedaan utamanya? Suka ingatan atau implikasi kinerja

Perbedaan antara sumber daya statis dan dinamis terjadi ketika objek yang mendasarinya berubah. Jika Kuas Anda yang ditentukan dalam koleksi Sumber Daya diakses dalam kode dan disetel ke instance objek yang berbeda, Rectangle tidak akan mendeteksi perubahan ini.

Sumber Daya Statis diambil sekali dengan merujuk elemen dan digunakan untuk seumur hidup sumber daya. Padahal, DynamicResources mengambil setiap kali digunakan.

Kelemahan dari sumber daya Dinamis adalah bahwa mereka cenderung menurunkan kinerja aplikasi.

Apakah ada aturan di WPF seperti "kuas selalu statis" dan "templat selalu dinamis" dll.?

Praktik terbaik adalah menggunakan Sumber Daya Statis kecuali ada alasan khusus seperti Anda ingin mengubah sumber daya dalam kode di belakang secara dinamis. Contoh lain contoh di mana Anda ingin t menggunakan resoruces dinamis termasuk ketika Anda menggunakan SystemBrushes, SystenFonts dan Parameter Sistem.

CharithJ
sumber
7

Semua jawaban bermanfaat, hanya ingin menambahkan satu lagi use case.

Dalam skenario WPF komposit, kontrol pengguna Anda dapat menggunakan sumber daya yang ditentukan dalam jendela induk lain / kontrol (yang akan meng-host kontrol pengguna ini) dengan merujuk sumber daya tersebut sebagai DynamicResource.

Seperti yang disebutkan oleh orang lain, Staticresource akan dilihat pada waktu kompilasi. Kontrol pengguna tidak dapat merujuk ke sumber daya yang ditentukan dalam kontrol hosting / induk. Padahal, DynamicResource dapat digunakan dalam kasus ini.

Manish Basantani
sumber
3

Manfaat penting dari sumber daya dinamis

jika startup aplikasi membutuhkan waktu yang sangat lama, Anda harus menggunakan sumber daya dinamis, karena sumber daya statis selalu dimuat saat jendela atau aplikasi dibuat, sedangkan sumber daya dinamis dimuat saat pertama kali digunakan.

Namun, Anda tidak akan melihat manfaat apa pun kecuali sumber daya Anda sangat besar dan kompleks.

zamoldar
sumber
Untuk DynamicResources, apakah itu menciptakan masalah kinerja hanya sekali (digunakan untuk pertama kali) atau apakah itu setiap kali elemen digunakan?
Morgane
dalam hal ini bidang yang paling sering digunakan harus sumber daya statis, bidang yang digunakan khusus dapat menjadi dinamis, yaitu untuk sumber daya jendela utama statis dan sumber daya jendela dialog bisa dinamis
zamoldar
2

Sumber daya dinamis hanya dapat digunakan ketika properti sedang disetel pada objek yang berasal dari objek dependensi atau dapat dibekukan di mana sumber daya statis dapat digunakan di mana saja. Anda dapat memisahkan seluruh kontrol menggunakan sumber daya statis.

Sumber daya statis digunakan dalam kondisi berikut:

  1. Ketika sumber daya reaksi berubah saat runtime tidak diperlukan.
  2. Jika Anda membutuhkan kinerja yang baik dengan banyak sumber daya.
  3. Sementara referensi sumber daya dalam kamus yang sama.

Sumber daya dinamis:

  1. Nilai properti atau tema setter style tidak diketahui sampai runtime
    • Ini termasuk pengaturan sistem, aplikasi, tema berbasis
    • Ini juga termasuk referensi ke depan.
  2. Referensi sumber daya besar yang mungkin tidak dimuat saat halaman, jendela, kontrol pengguna memuat.
  3. Merujuk gaya tema dalam kontrol khusus.
iaminvinicble
sumber