Referensi sumber daya ResourceDictionary dan XAML

Anda dapat menentukan UI atau sumber daya untuk aplikasi Anda menggunakan XAML. Sumber daya biasanya merupakan definisi dari beberapa objek yang Anda harapkan untuk digunakan lebih dari sekali. Untuk merujuk ke sumber daya XAML nanti, Anda menentukan kunci untuk sumber daya yang bertindak seperti namanya. Anda dapat mereferensikan sumber daya di seluruh aplikasi atau dari halaman XAML apa pun di dalamnya. Anda dapat menentukan sumber daya Anda menggunakan elemen ResourceDictionary dari Windows Runtime XAML. Kemudian, Anda dapat mereferensikan sumber daya Anda dengan menggunakan ekstensi markup StaticResource atau ekstensi markup ThemeResource.

Elemen XAML yang mungkin ingin Anda deklarasikan paling sering karena sumber daya XAML termasuk Gaya, ControlTemplate, komponen animasi, dan subkelas Brush . Di sini, kami menjelaskan cara menentukan sumber daya ResourceDictionary dan keyed, dan bagaimana sumber daya XAML berhubungan dengan sumber daya lain yang Anda tentukan sebagai bagian dari paket aplikasi atau aplikasi Anda. Kami juga menjelaskan fitur lanjutan kamus sumber daya seperti MergedDictionaries dan ThemeDictionaries.

Prasyarat

Pemahaman yang kuat tentang markup XAML. Sebaiknya baca gambaran umum XAML.

Menentukan dan menggunakan sumber daya XAML

Sumber daya XAML adalah objek yang dirujuk dari markup lebih dari sekali. Sumber daya ditentukan dalam ResourceDictionary, biasanya dalam file terpisah atau di bagian atas halaman markup, seperti ini.

<Page
    x:Class="MSDNSample.MainPage"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">

    <Page.Resources>
        <x:String x:Key="greeting">Hello world</x:String>
        <x:String x:Key="goodbye">Goodbye world</x:String>
    </Page.Resources>

    <TextBlock Text="{StaticResource greeting}" Foreground="Gray" VerticalAlignment="Center"/>
</Page>

Dalam contoh ini:

  • <Page.Resources>…</Page.Resources> - Mendefinisikan kamus sumber daya.
  • <x:String> - Mendefinisikan sumber daya dengan kunci "salam".
  • {StaticResource greeting}- Mencari sumber daya dengan kunci "salam", yang ditetapkan ke properti Teks TextBlock.

Catatan Jangan membingungkan konsep yang terkait dengan ResourceDictionary dengan tindakan Build sumber daya, file resource (.resw), atau "sumber daya" lainnya yang dibahas dalam konteks penataan proyek kode yang menghasilkan paket aplikasi Anda.

Sumber daya tidak harus berupa string; mereka bisa menjadi objek yang dapat dibagikan, seperti gaya, templat, kuas, dan warna. Namun, kontrol, bentuk, dan FrameworkElementlainnya tidak dapat dibagikan, sehingga tidak dapat dinyatakan sebagai sumber daya yang dapat digunakan kembali. Untuk informasi selengkapnya tentang berbagi, lihat bagian sumber daya XAML harus dapat dibagikan nanti dalam topik ini.

Di sini, kuas dan string dinyatakan sebagai sumber daya dan digunakan oleh kontrol dalam halaman.

<Page
    x:Class="SpiderMSDN.MainPage"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">

    <Page.Resources>
        <SolidColorBrush x:Key="myFavoriteColor" Color="green"/>
        <x:String x:Key="greeting">Hello world</x:String>
    </Page.Resources>

    <TextBlock Foreground="{StaticResource myFavoriteColor}" Text="{StaticResource greeting}" VerticalAlignment="Top"/>
    <Button Foreground="{StaticResource myFavoriteColor}" Content="{StaticResource greeting}" VerticalAlignment="Center"/>
</Page>

Semua sumber daya harus memiliki kunci. Biasanya kunci tersebut adalah string yang didefinisikan dengan x:Key="myString". Namun, ada beberapa cara lain untuk menentukan kunci:

  • Gaya dan ControlTemplate memerlukan TargetType, dan akan menggunakan TargetType sebagai kunci jika x:Key tidak ditentukan. Dalam hal ini, kuncinya adalah objek Jenis aktual, bukan string. (Lihat contoh di bawah)
  • Sumber daya DataTemplate yang memiliki TargetType akan menggunakan TargetType sebagai kunci jika x:Key tidak ditentukan. Dalam hal ini, kuncinya adalah objek Jenis aktual, bukan string.
  • x:Name dapat digunakan alih-alih x:Key. Namun, x:Name juga menghasilkan kode di belakang bidang untuk sumber daya. Akibatnya, x:Name kurang efisien daripada x:Key karena bidang tersebut perlu diinisialisasi saat halaman dimuat.

Ekstensi markup StaticResource hanya dapat mengambil sumber daya dengan nama string (x:Key atau x:Name). Namun, kerangka kerja XAML juga mencari sumber daya gaya implisit (yang menggunakan TargetType daripada x:Key atau x:Name) ketika memutuskan gaya & templat mana yang akan digunakan untuk kontrol yang belum mengatur properti Style dan ContentTemplate atau ItemTemplate .

Di sini, Gaya memiliki kunci implisit typeof (Button), dan karena Tombol di bagian bawah halaman tidak menentukan properti Gaya , Gaya mencari gaya dengan kunci typeof(Button):

<Page
    x:Class="MSDNSample.MainPage"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">

    <Page.Resources>
        <Style TargetType="Button">
            <Setter Property="Background" Value="Red"/>
        </Style>
    </Page.Resources>
    <Grid>
       <!-- This button will have a red background. -->
       <Button Content="Button" Height="100" VerticalAlignment="Center" Width="100"/>
    </Grid>
</Page>

Untuk informasi selengkapnya tentang gaya implisit dan cara kerjanya, lihat Kontrol gaya dan Templat kontrol.

Mencari sumber daya dalam kode

Anda mengakses anggota kamus sumber daya seperti kamus lainnya.

Peringatan

Saat Anda melakukan pencarian sumber daya dalam kode, hanya sumber daya dalam Page.Resources kamus yang dilihat. Tidak seperti ekstensi markup StaticResource, kode tidak kembali ke Application.Resources kamus jika sumber daya tidak ditemukan di kamus pertama.

 

Contoh ini menunjukkan cara mengambil redButtonStyle sumber daya dari kamus sumber daya halaman:

<Page
    x:Class="MSDNSample.MainPage"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">

    <Page.Resources>
        <Style TargetType="Button" x:Key="redButtonStyle">
            <Setter Property="Background" Value="red"/>
        </Style>
    </Page.Resources>
</Page>
    public sealed partial class MainPage : Page
    {
        public MainPage()
        {
            this.InitializeComponent();
            Style redButtonStyle = (Style)this.Resources["redButtonStyle"];
        }
    }
    MainPage::MainPage()
    {
        InitializeComponent();
        Windows::UI::Xaml::Style style = Resources().TryLookup(winrt::box_value(L"redButtonStyle")).as<Windows::UI::Xaml::Style>();
    }

Untuk mencari sumber daya di seluruh aplikasi dari kode, gunakan Application.Current.Resources untuk mendapatkan kamus sumber daya aplikasi, seperti yang ditunjukkan di sini.

<Application
    x:Class="MSDNSample.App"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:local="using:SpiderMSDN">
    <Application.Resources>
        <Style TargetType="Button" x:Key="appButtonStyle">
            <Setter Property="Background" Value="red"/>
        </Style>
    </Application.Resources>

</Application>
    public sealed partial class MainPage : Page
    {
        public MainPage()
        {
            this.InitializeComponent();
            Style appButtonStyle = (Style)Application.Current.Resources["appButtonStyle"];
        }
    }
    MainPage::MainPage()
    {
        InitializeComponent();
        Windows::UI::Xaml::Style style = Application::Current().Resources()
                                                               .TryLookup(winrt::box_value(L"appButtonStyle"))
                                                               .as<Windows::UI::Xaml::Style>();
    }

Anda juga dapat menambahkan sumber daya aplikasi dalam kode.

Ada dua hal yang perlu diingat ketika melakukan ini.

  • Pertama, Anda perlu menambahkan sumber daya sebelum halaman mana pun mencoba menggunakan sumber daya.
  • Kedua, Anda tidak dapat menambahkan sumber daya di konstruktor Aplikasi.

Anda dapat menghindari kedua masalah jika Anda menambahkan sumber daya dalam metode Application.OnLaunched , seperti ini.

// App.xaml.cs
    
sealed partial class App : Application
{
    protected override void OnLaunched(LaunchActivatedEventArgs e)
    {
        Frame rootFrame = Window.Current.Content as Frame;
        if (rootFrame == null)
        {
            SolidColorBrush brush = new SolidColorBrush(Windows.UI.Color.FromArgb(255, 0, 255, 0)); // green
            this.Resources["brush"] = brush;
            // … Other code that VS generates for you …
        }
    }
}
// App.cpp

void App::OnLaunched(LaunchActivatedEventArgs const& e)
{
    Frame rootFrame{ nullptr };
    auto content = Window::Current().Content();
    if (content)
    {
        rootFrame = content.try_as<Frame>();
    }

    // Do not repeat app initialization when the Window already has content,
    // just ensure that the window is active
    if (rootFrame == nullptr)
    {
        Windows::UI::Xaml::Media::SolidColorBrush brush{ Windows::UI::ColorHelper::FromArgb(255, 0, 255, 0) };
        Resources().Insert(winrt::box_value(L"brush"), winrt::box_value(brush));
        // … Other code that VS generates for you …

Setiap FrameworkElement dapat memiliki ResourceDictionary

FrameworkElement adalah kelas dasar yang mengontrol warisan, dan memiliki properti Sumber Daya . Jadi, Anda dapat menambahkan kamus sumber daya lokal ke FrameworkElement apa pun.

Di sini, Halaman dan Batas memiliki kamus sumber daya, dan keduanya memiliki sumber daya yang disebut "salam". TextBlock bernama 'textBlock2' berada di dalam Batas, sehingga pencarian sumber dayanya terlihat terlebih dahulu ke sumber daya Batas, lalu sumber daya Halaman, lalu sumber daya Aplikasi. TextBlock akan membaca "Hola mundo".

Untuk mengakses sumber daya elemen tersebut dari kode, gunakan properti Sumber Daya elemen tersebut. Mengakses sumber daya FrameworkElement dalam kode, bukan XAML, hanya akan terlihat dalam kamus tersebut, bukan dalam kamus elemen induk.

<Page
    x:Class="MSDNSample.MainPage"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">
    <Page.Resources>
        <x:String x:Key="greeting">Hello world</x:String>
    </Page.Resources>
    
    <StackPanel>
        <!-- Displays "Hello world" -->
        <TextBlock x:Name="textBlock1" Text="{StaticResource greeting}"/>

        <Border x:Name="border">
            <Border.Resources>
                <x:String x:Key="greeting">Hola mundo</x:String>
            </Border.Resources>
            <!-- Displays "Hola mundo" -->
            <TextBlock x:Name="textBlock2" Text="{StaticResource greeting}"/>
        </Border>

        <!-- Displays "Hola mundo", set in code. -->
        <TextBlock x:Name="textBlock3"/>
    </StackPanel>
</Page>

    public sealed partial class MainPage : Page
    {
        public MainPage()
        {
            this.InitializeComponent();
            textBlock3.Text = (string)border.Resources["greeting"];
        }
    }
    MainPage::MainPage()
    {
        InitializeComponent();
        textBlock3().Text(unbox_value<hstring>(border().Resources().TryLookup(winrt::box_value(L"greeting"))));
    }

Kamus sumber daya gabungan

Kamus sumber daya gabungan menggabungkan satu kamus sumber daya ke dalam kamus sumber daya lainnya, biasanya dalam file lain.

Tips Anda dapat membuat file kamus sumber daya di Microsoft Visual Studio dengan menggunakan Tambahkan > Item Baru... > Opsi Kamus Sumber Daya dari menu Proyek .

Di sini, Anda menentukan kamus sumber daya dalam file XAML terpisah yang disebut Dictionary1.xaml.

<!-- Dictionary1.xaml -->
<ResourceDictionary
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" 
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:local="using:MSDNSample">

    <SolidColorBrush x:Key="brush" Color="Red"/>

</ResourceDictionary>

Untuk menggunakan kamus tersebut, Anda menggabungkannya dengan kamus halaman Anda:

<Page
    x:Class="MSDNSample.MainPage"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">
    <Page.Resources>
        <ResourceDictionary>
            <ResourceDictionary.MergedDictionaries>
                <ResourceDictionary Source="Dictionary1.xaml"/>
            </ResourceDictionary.MergedDictionaries>

            <x:String x:Key="greeting">Hello world</x:String>

        </ResourceDictionary>
    </Page.Resources>

    <TextBlock Foreground="{StaticResource brush}" Text="{StaticResource greeting}" VerticalAlignment="Center"/>
</Page>

Inilah yang terjadi dalam contoh ini. Dalam <Page.Resources>, Anda mendeklarasikan <ResourceDictionary>. Kerangka kerja XAML secara implisit membuat kamus sumber daya untuk Anda ketika Anda menambahkan sumber daya ke <Page.Resources>; namun, dalam hal ini, Anda tidak menginginkan kamus sumber daya apa pun, Anda menginginkannya yang berisi kamus gabungan.

Jadi Anda menyatakan <ResourceDictionary>, lalu menambahkan hal-hal ke koleksinya <ResourceDictionary.MergedDictionaries> . Masing-masing entri tersebut mengambil formulir <ResourceDictionary Source="Dictionary1.xaml"/>. Untuk menambahkan lebih dari satu kamus, cukup tambahkan <ResourceDictionary Source="Dictionary2.xaml"/> entri setelah entri pertama.

Setelah <ResourceDictionary.MergedDictionaries>…</ResourceDictionary.MergedDictionaries>, Anda dapat secara opsional menempatkan sumber daya tambahan di kamus utama Anda. Anda menggunakan sumber daya dari gabungan ke kamus seperti kamus biasa. Dalam contoh di atas, {StaticResource brush} menemukan sumber daya dalam kamus turunan/gabungan (Dictionary1.xaml), sambil {StaticResource greeting} menemukan sumber dayanya di kamus halaman utama.

Dalam urutan pencarian sumber daya, kamus MergedDictionaries diperiksa hanya setelah pemeriksaan semua sumber daya kunci lainnya dari ResourceDictionary tersebut. Setelah mencari tingkat tersebut, pencarian mencapai kamus gabungan, dan setiap item di MergedDictionaries dicentang. Jika ada beberapa kamus gabungan, kamus ini diperiksa dalam inversi urutan di mana kamus tersebut dideklarasikan dalam properti MergedDictionaries . Dalam contoh berikut, jika Dictionary2.xaml dan Dictionary1.xaml mendeklarasikan kunci yang sama, kunci dari Dictionary2.xaml digunakan terlebih dahulu karena terakhir dalam kumpulan MergedDictionaries .

<Page
    x:Class="MSDNSample.MainPage"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">
    <Page.Resources>
        <ResourceDictionary>
            <ResourceDictionary.MergedDictionaries>
                <ResourceDictionary Source="Dictionary1.xaml"/>
                <ResourceDictionary Source="Dictionary2.xaml"/>
            </ResourceDictionary.MergedDictionaries>
        </ResourceDictionary>
    </Page.Resources>

    <TextBlock Foreground="{StaticResource brush}" Text="greetings!" VerticalAlignment="Center"/>
</Page>

Dalam cakupan salah satu ResourceDictionary, kamus diperiksa untuk keunikan utama. Namun, cakupan tersebut tidak meluas di berbagai item dalam file MergedDictionaries yang berbeda.

Anda dapat menggunakan kombinasi urutan pencarian dan kurangnya penegakan kunci unik di seluruh cakupan kamus gabungan untuk membuat urutan nilai fallback sumber daya ResourceDictionary . Misalnya, Anda dapat menyimpan preferensi pengguna untuk warna kuas tertentu dalam kamus sumber daya gabungan terakhir dalam urutan, menggunakan kamus sumber daya yang disinkronkan ke data status aplikasi dan preferensi pengguna Anda. Namun, jika belum ada preferensi pengguna, Anda dapat menentukan string kunci yang sama untuk sumber daya ResourceDictionary dalam file MergedDictionaries awal, dan dapat berfungsi sebagai nilai fallback. Ingatlah bahwa nilai apa pun yang Anda berikan dalam kamus sumber daya utama selalu diperiksa sebelum kamus gabungan diperiksa, jadi jika Anda ingin menggunakan teknik fallback, jangan tentukan sumber daya tersebut dalam kamus sumber daya utama.

Sumber daya tema dan kamus tema

ThemeResource mirip dengan StaticResource, tetapi pencarian sumber daya dievaluasi kembali saat tema berubah.

Dalam contoh ini, Anda mengatur latar depan TextBlock ke nilai dari tema saat ini.

<TextBlock Text="hello world" Foreground="{ThemeResource FocusVisualWhiteStrokeThemeBrush}" VerticalAlignment="Center"/>

Kamus tema adalah jenis khusus dari kamus gabungan yang menyimpan sumber daya yang bervariasi dengan tema yang saat ini digunakan pengguna pada perangkatnya. Misalnya, tema "terang" mungkin menggunakan kuas warna putih sedangkan tema "gelap" mungkin menggunakan kuas warna gelap. Kuas mengubah sumber daya yang diselesaikannya, tetapi jika tidak, komposisi kontrol yang menggunakan kuas sebagai sumber daya bisa sama. Untuk mereproduksi perilaku peralihan tema dalam templat dan gaya Anda sendiri, alih-alih menggunakan MergedDictionaries sebagai properti untuk menggabungkan item ke dalam kamus utama, gunakan properti ThemeDictionaries .

Setiap elemen ResourceDictionary dalam ThemeDictionaries harus memiliki nilai x:Key . Nilainya adalah string yang menamai tema yang relevan—misalnya, "Default", "Gelap", "Terang", atau "HighContrast". Biasanya, Dictionary1 dan Dictionary2 akan menentukan sumber daya yang memiliki nama yang sama tetapi nilai yang berbeda.

Di sini, Anda menggunakan teks merah untuk tema terang dan teks biru untuk tema gelap.

<!-- Dictionary1.xaml -->
<ResourceDictionary
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" 
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:local="using:MSDNSample">

    <SolidColorBrush x:Key="brush" Color="Red"/>

</ResourceDictionary>

<!-- Dictionary2.xaml -->
<ResourceDictionary
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" 
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:local="using:MSDNSample">

    <SolidColorBrush x:Key="brush" Color="blue"/>

</ResourceDictionary>

Dalam contoh ini, Anda mengatur latar depan TextBlock ke nilai dari tema saat ini.

<Page
    x:Class="MSDNSample.MainPage"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">
    <Page.Resources>
        <ResourceDictionary>
            <ResourceDictionary.ThemeDictionaries>
                <ResourceDictionary Source="Dictionary1.xaml" x:Key="Light"/>
                <ResourceDictionary Source="Dictionary2.xaml" x:Key="Dark"/>
            </ResourceDictionary.ThemeDictionaries>
        </ResourceDictionary>
    </Page.Resources>
    <TextBlock Foreground="{StaticResource brush}" Text="hello world" VerticalAlignment="Center"/>
</Page>

Untuk kamus tema, kamus aktif yang akan digunakan untuk pencarian sumber daya berubah secara dinamis, setiap kali ekstensi markup ThemeResource digunakan untuk membuat referensi dan sistem mendeteksi perubahan tema. Perilaku pencarian yang dilakukan oleh sistem didasarkan pada pemetaan tema aktif ke x:Kunci kamus tema tertentu.

Ini dapat berguna untuk memeriksa cara kamus tema disusun dalam sumber daya desain XAML default, yang paralel dengan templat yang digunakan Windows Runtime secara default untuk kontrolnya. Buka file XAML di \(Program Files)\Windows Kits\10\DesignTime\CommonConfiguration\Neutral\UAP\<SDK version>\Generic menggunakan editor teks atau IDE Anda. Perhatikan bagaimana kamus tema didefinisikan terlebih dahulu dalam generic.xaml, dan bagaimana setiap kamus tema mendefinisikan kunci yang sama. Setiap kunci tersebut kemudian dirujuk oleh elemen komposisi dalam berbagai elemen kunci yang berada di luar kamus tema dan didefinisikan nanti di XAML. Ada juga file themeresources.xaml terpisah untuk desain yang hanya berisi sumber daya tema dan templat tambahan, bukan templat kontrol default. Area tema adalah duplikat dari apa yang akan Anda lihat di generic.xaml.

Saat Anda menggunakan alat desain XAML untuk mengedit salinan gaya dan templat, bagian ekstrak alat desain dari kamus sumber daya desain XAML dan menempatkannya sebagai salinan lokal elemen kamus XAML yang merupakan bagian dari aplikasi dan proyek Anda.

Untuk informasi selengkapnya dan untuk daftar sumber daya tema dan sistem khusus yang tersedia untuk aplikasi Anda, lihat sumber daya tema XAML.

Perilaku pencarian untuk referensi sumber daya XAML

Perilaku pencarian adalah istilah yang menjelaskan bagaimana sistem sumber daya XAML mencoba menemukan sumber daya XAML. Pencarian terjadi ketika kunci dirujuk sebagai referensi sumber daya XAML dari suatu tempat di XAML aplikasi. Pertama, sistem sumber daya memiliki perilaku yang dapat diprediksi di mana ia akan memeriksa keberadaan sumber daya berdasarkan cakupan. Jika sumber daya tidak ditemukan dalam cakupan awal, cakupan akan diperluas. Perilaku pencarian berlanjut di seluruh lokasi dan cakupan bahwa sumber daya XAML mungkin dapat ditentukan oleh aplikasi atau oleh sistem. Jika semua kemungkinan upaya pencarian sumber daya gagal, kesalahan sering menghasilkan. Biasanya dimungkinkan untuk menghilangkan kesalahan ini selama proses pengembangan.

Perilaku pencarian untuk referensi sumber daya XAML dimulai dengan objek tempat penggunaan aktual diterapkan dan properti Sumber Dayanya sendiri. Jika ResourceDictionary ada di sana, ResourceDictionary tersebut dicentang untuk item yang memiliki kunci yang diminta. Tingkat pencarian pertama ini jarang relevan karena Anda biasanya tidak menentukan lalu mereferensikan sumber daya pada objek yang sama. Bahkan, properti Sumber Daya sering tidak ada di sini. Anda dapat membuat referensi sumber daya XAML dari hampir di mana saja di XAML; Anda tidak terbatas pada properti subkelas FrameworkElement .

Urutan pencarian kemudian memeriksa objek induk berikutnya di pohon objek runtime aplikasi. Jika FrameworkElement.Resources ada dan menyimpan ResourceDictionary, item kamus dengan string kunci yang ditentukan diminta. Jika sumber daya ditemukan, urutan pencarian berhenti dan objek disediakan ke lokasi tempat referensi dibuat. Jika tidak, perilaku pencarian maju ke tingkat induk berikutnya menuju akar pohon objek. Pencarian berlanjut secara rekursif ke atas sampai elemen akar XAML tercapai, menghabiskan pencarian semua lokasi sumber daya langsung yang mungkin.

Catatan

Ini adalah praktik umum untuk menentukan semua sumber daya langsung di tingkat akar halaman, baik untuk memanfaatkan perilaku pencarian sumber daya ini dan juga sebagai konvensi gaya markup XAML.

Jika sumber daya yang diminta tidak ditemukan di sumber daya langsung, langkah pencarian berikutnya adalah memeriksa properti Application.Resources . Application.Resources adalah tempat terbaik untuk menempatkan sumber daya khusus aplikasi apa pun yang dirujuk oleh beberapa halaman dalam struktur navigasi aplikasi Anda.

Penting

Urutan sumber daya yang ditambahkan ke ResourceDictionary memengaruhi urutan penerapannya. Kamus mengambil XamlControlsResources alih banyak kunci sumber daya default dan oleh karena itu harus ditambahkan ke Application.Resources terlebih dahulu sehingga tidak mengambil alih gaya atau sumber daya kustom lainnya di aplikasi Anda.

Templat kontrol memiliki lokasi lain yang mungkin dalam pencarian referensi: kamus tema. Kamus tema adalah satu file XAML yang memiliki elemen ResourceDictionary sebagai akarnya. Kamus tema mungkin merupakan kamus gabungan dari Application.Resources. Kamus tema mungkin juga merupakan kamus tema khusus kontrol untuk kontrol kustom bertempur.

Terakhir, ada pencarian sumber daya terhadap sumber daya platform. Sumber daya platform mencakup templat kontrol yang ditentukan untuk setiap tema antarmuka pengguna sistem, dan yang menentukan tampilan default semua kontrol yang Anda gunakan untuk UI di aplikasi Windows Runtime. Sumber daya platform juga mencakup sekumpulan sumber daya bernama yang terkait dengan tampilan dan tema di seluruh sistem. Sumber daya ini secara teknis adalah item MergedDictionaries , dan dengan demikian tersedia untuk pencarian dari XAML atau kode setelah aplikasi dimuat. Misalnya, sumber daya tema sistem menyertakan sumber daya bernama "SystemColorWindowTextColor" yang menyediakan definisi Warna untuk mencocokkan warna teks aplikasi dengan warna teks jendela sistem yang berasal dari sistem operasi dan preferensi pengguna. Gaya XAML lainnya untuk aplikasi Anda dapat merujuk ke gaya ini, atau kode Anda bisa mendapatkan nilai pencarian sumber daya (dan melemparkannya ke Warna dalam contoh kasus).

Untuk informasi selengkapnya dan untuk daftar sumber daya tema dan sistem khusus yang tersedia untuk aplikasi Windows yang menggunakan XAML, lihat sumber daya tema XAML.

Jika kunci yang diminta masih belum ditemukan di salah satu lokasi ini, kesalahan/pengecualian penguraian XAML terjadi. Dalam keadaan tertentu, pengecualian penguraian XAML mungkin merupakan pengecualian run-time yang tidak terdeteksi baik oleh tindakan kompilasi markup XAML, atau oleh lingkungan desain XAML.

Karena perilaku pencarian berjenjang untuk kamus sumber daya, Anda dapat dengan sengaja menentukan beberapa item sumber daya yang masing-masing memiliki nilai string yang sama dengan kunci, selama setiap sumber daya didefinisikan pada tingkat yang berbeda. Dengan kata lain, meskipun kunci harus unik dalam ResourceDictionary tertentu, persyaratan keunikan tidak meluas ke urutan perilaku pencarian secara keseluruhan. Selama pencarian, hanya objek pertama yang berhasil diambil yang digunakan untuk referensi sumber daya XAML, lalu pencarian berhenti. Anda dapat menggunakan perilaku ini untuk meminta sumber daya XAML yang sama dengan kunci di berbagai posisi dalam XAML aplikasi Anda tetapi mendapatkan sumber daya yang berbeda kembali, tergantung pada cakupan tempat referensi sumber daya XAML dibuat dan bagaimana pencarian tertentu berperilaku.

Meneruskan referensi dalam ResourceDictionary

Referensi sumber daya XAML dalam kamus sumber daya tertentu harus mereferensikan sumber daya yang telah ditentukan dengan kunci, dan sumber daya tersebut harus muncul secara leksikal sebelum referensi sumber daya. Referensi penerusan tidak dapat diselesaikan dengan referensi sumber daya XAML. Untuk alasan ini, jika Anda menggunakan referensi sumber daya XAML dari dalam sumber daya lain, Anda harus merancang struktur kamus sumber daya Anda sehingga sumber daya yang digunakan oleh sumber daya lain ditentukan terlebih dahulu dalam kamus sumber daya.

Sumber daya yang ditentukan di tingkat aplikasi tidak dapat membuat referensi ke sumber daya langsung. Ini setara dengan mencoba referensi penerusan, karena sumber daya aplikasi benar-benar diproses terlebih dahulu (ketika aplikasi pertama kali dimulai, dan sebelum konten halaman navigasi dimuat). Namun, sumber daya langsung apa pun dapat membuat referensi ke sumber daya aplikasi, dan ini dapat menjadi teknik yang berguna untuk menghindari situasi referensi maju.

Sumber daya XAML harus dapat dibagikan

Agar objek ada di ResourceDictionary, objek tersebut harus dapat dibagikan.

Menjadi dapat dibagikan diperlukan karena, ketika pohon objek aplikasi dibangun dan digunakan pada waktu proses, objek tidak dapat ada di beberapa lokasi di pohon. Secara internal, sistem sumber daya membuat salinan nilai sumber daya untuk digunakan dalam grafik objek aplikasi Anda saat setiap sumber daya XAML diminta.

ResourceDictionary dan Windows Runtime XAML secara umum mendukung objek ini untuk penggunaan yang dapat dibagikan:

Anda juga dapat menggunakan jenis kustom sebagai sumber daya yang dapat dibagikan jika Anda mengikuti pola implementasi yang diperlukan. Anda menentukan kelas tersebut dalam kode dukungan Anda (atau dalam komponen runtime yang Anda sertakan) lalu membuat instans kelas tersebut di XAML sebagai sumber daya. Contohnya adalah sumber data objek dan implementasi IValueConverter untuk pengikatan data.

Jenis kustom harus memiliki konstruktor default, karena itulah yang digunakan pengurai XAML untuk membuat instans kelas. Jenis kustom yang digunakan sebagai sumber daya tidak dapat memiliki kelas UIElement dalam pewarisannya, karena UIElement tidak pernah dapat dibagikan (selalu dimaksudkan untuk mewakili persis satu elemen UI yang ada pada satu posisi dalam grafik objek aplikasi runtime Anda).

Cakupan penggunaan UserControl

Elemen UserControl memiliki situasi khusus untuk perilaku pencarian sumber daya karena memiliki konsep cakupan definisi yang melekat dan cakupan penggunaan. UserControl yang membuat referensi sumber daya XAML dari cakupan definisinya harus dapat mendukung pencarian sumber daya tersebut dalam urutan pencarian cakupan definisinya sendiri—yaitu, sumber daya aplikasi tidak dapat mengakses sumber daya aplikasi. Dari cakupan penggunaan UserControl, referensi sumber daya diperlakukan sebagai berada dalam urutan pencarian terhadap akar halaman penggunaannya (sama seperti referensi sumber daya lain yang dibuat dari objek di pohon objek yang dimuat) dan dapat mengakses sumber daya aplikasi.

ResourceDictionary dan XamlReader.Load

Anda dapat menggunakan ResourceDictionary sebagai root atau bagian dari input XAML untuk metode XamlReader.Load . Anda juga dapat menyertakan referensi sumber daya XAML dalam XAML tersebut jika semua referensi tersebut sepenuhnya mandiri dalam XAML yang dikirimkan untuk dimuat. XamlReader.Load mengurai XAML dalam konteks yang tidak mengetahui objek ResourceDictionary lainnya, bahkan Application.Resources. Selain itu, jangan gunakan {ThemeResource} dari dalam XAML yang dikirimkan ke XamlReader.Load.

Menggunakan ResourceDictionary dari kode

Sebagian besar skenario untuk ResourceDictionary ditangani secara eksklusif di XAML. Anda mendeklarasikan kontainer ResourceDictionary dan sumber daya dalam sebagai file XAML atau set simpul XAML dalam file definisi UI. Kemudian Anda menggunakan referensi sumber daya XAML untuk meminta sumber daya tersebut dari bagian lain dari XAML. Namun, ada skenario tertentu di mana aplikasi Anda mungkin ingin menyesuaikan konten ResourceDictionary menggunakan kode yang dijalankan saat aplikasi berjalan, atau setidaknya untuk mengkueri konten ResourceDictionary untuk melihat apakah sumber daya sudah ditentukan. Panggilan kode ini dilakukan pada instans ResourceDictionary, jadi Anda harus terlebih dahulu mengambilnya—baik ResourceDictionary langsung di suatu tempat di pohon objek dengan mendapatkan FrameworkElement.Resources, atau Application.Current.Resources.

Dalam kode C# atau Microsoft Visual Basic, Anda dapat mereferensikan sumber daya dalam ResourceDictionary tertentu dengan menggunakan pengindeks (Item). ResourceDictionary adalah kamus berkode string, sehingga pengindeks menggunakan kunci string alih-alih indeks bilangan bulat. Dalam kode ekstensi komponen Visual C++ (C++/CX), gunakan Pencarian.

Saat menggunakan kode untuk memeriksa atau mengubah ResourceDictionary, perilaku untuk API seperti Pencarian atau Item tidak melintasi dari sumber daya langsung ke sumber daya aplikasi; itu adalah perilaku pengurai XAML yang hanya terjadi saat halaman XAML dimuat. Pada waktu proses, cakupan untuk kunci dimuat sendiri ke instans ResourceDictionary yang Anda gunakan pada saat itu. Namun, cakupan itu memang meluas ke MergedDictionaries.

Selain itu, jika Anda meminta kunci yang tidak ada di ResourceDictionary, mungkin tidak ada kesalahan; nilai pengembalian mungkin hanya disediakan sebagai null. Namun, Anda mungkin masih mendapatkan kesalahan, jika Anda mencoba menggunakan null yang dikembalikan sebagai nilai. Kesalahan akan berasal dari setter properti, bukan panggilan ResourceDictionary Anda. Satu-satunya cara Anda menghindari kesalahan adalah jika properti menerima null sebagai nilai yang valid. Perhatikan bagaimana perilaku ini berbeda dengan perilaku pencarian XAML pada waktu penguraian XAML; kegagalan untuk menyelesaikan kunci yang disediakan dari XAML pada waktu penguraian mengakibatkan kesalahan penguraian XAML, bahkan dalam kasus di mana properti dapat menerima null.

Kamus sumber daya gabungan disertakan ke dalam cakupan indeks kamus sumber daya utama yang mereferensikan kamus gabungan pada run time. Dengan kata lain, Anda dapat menggunakan Item atau Pencarian kamus utama untuk menemukan objek apa pun yang benar-benar ditentukan dalam kamus gabungan. Dalam hal ini, perilaku pencarian memang menyerupai perilaku pencarian XAML parse-time: jika ada beberapa objek dalam kamus gabungan yang masing-masing memiliki kunci yang sama, objek dari kamus terakhir ditambahkan dikembalikan.

Anda diizinkan untuk menambahkan item ke ResourceDictionary yang ada dengan memanggil Tambahkan (C# atau Visual Basic) atau Sisipkan (C++/CX). Anda dapat menambahkan item ke sumber daya langsung atau sumber daya aplikasi. Salah satu panggilan API ini memerlukan kunci, yang memenuhi persyaratan bahwa setiap item dalam ResourceDictionary harus memiliki kunci. Namun, item yang Anda tambahkan ke ResourceDictionary pada run time tidak relevan dengan referensi sumber daya XAML. Pencarian yang diperlukan untuk referensi sumber daya XAML terjadi ketika XAML pertama kali diurai saat aplikasi dimuat (atau perubahan tema terdeteksi). Sumber daya yang ditambahkan ke koleksi pada waktu proses tidak tersedia, dan mengubah ResourceDictionary tidak membatalkan sumber daya yang sudah diambil darinya bahkan jika Anda mengubah nilai sumber daya tersebut.

Anda juga dapat menghapus item dari ResourceDictionary pada run time, membuat salinan beberapa atau semua item, atau operasi lainnya. Daftar anggota untuk ResourceDictionary menunjukkan API mana yang tersedia. Perhatikan bahwa karena ResourceDictionary memiliki API yang diproyeksikan untuk mendukung antarmuka pengumpulan yang mendasarinya, opsi API Anda berbeda tergantung pada apakah Anda menggunakan C# atau Visual Basic versus C++/CX.

ResourceDictionary dan pelokalan

ResourceDictionary XAML awalnya mungkin berisi string yang akan dilokalkan. Jika demikian, simpan string ini sebagai sumber daya proyek alih-alih di ResourceDictionary. Keluarkan string dari XAML, dan sebagai gantinya berikan elemen pemilik nilai direktif x:Uid. Kemudian, tentukan sumber daya dalam file sumber daya. Berikan nama sumber daya dalam formulir XUIDValue.PropertyName dan nilai sumber daya string yang harus dilokalkan.

Pencarian sumber daya kustom

Untuk skenario lanjutan, Anda dapat menerapkan kelas yang dapat memiliki perilaku berbeda dari perilaku pencarian referensi sumber daya XAML yang dijelaskan dalam topik ini. Untuk melakukan ini, Anda menerapkan kelas CustomXamlResourceLoader, lalu Anda dapat mengakses perilaku tersebut dengan menggunakan ekstensi markup CustomResource untuk referensi sumber daya daripada menggunakan StaticResource atau ThemeResource. Sebagian besar aplikasi tidak akan memiliki skenario yang memerlukan ini. Untuk informasi selengkapnya, lihat CustomXamlResourceLoader.