Sumber daya tema XAML

Sumber daya tema di XAML adalah sekumpulan sumber daya yang menerapkan nilai yang berbeda tergantung pada tema sistem mana yang aktif. Ada 3 tema yang didukung kerangka kerja XAML: "Terang", "Gelap", dan "HighContrast".

Prasyarat: Topik ini mengasumsikan bahwa Anda telah membaca referensi sumber daya ResourceDictionary dan XAML.

Sumber daya tema v. sumber daya statis

Ada dua ekstensi markup XAML yang dapat mereferensikan sumber daya XAML dari kamus sumber daya XAML yang ada: ekstensi markup {StaticResource} dan ekstensi markup {ThemeResource}.

Evaluasi ekstensi markup {ThemeResource} terjadi saat aplikasi dimuat dan kemudian setiap kali tema berubah pada runtime. Ini biasanya hasil dari pengguna yang mengubah pengaturan perangkat mereka atau dari perubahan terprogram dalam aplikasi yang mengubah temanya saat ini.

Sebaliknya, ekstensi markup {StaticResource} dievaluasi hanya saat XAML pertama kali dimuat oleh aplikasi. Ini tidak diperbarui. Ini mirip dengan temukan dan ganti di XAML Anda dengan nilai runtime aktual saat peluncuran aplikasi.

Sumber daya tema dalam struktur kamus sumber daya

Setiap sumber daya tema adalah bagian dari file XAML themeresources.xaml. Untuk tujuan desain, themeresources.xaml tersedia di \(Program Files)\Windows Kits\10\DesignTime\CommonConfiguration\Neutral\UAP\<SDK version>\Generic folder dari penginstalan Windows Software Development Kit (SDK). Kamus sumber daya di themeresources.xaml juga diproduksi ulang dalam generic.xaml dalam direktori yang sama.

Windows Runtime tidak menggunakan file fisik ini untuk pencarian runtime. Itulah sebabnya mereka secara khusus berada di folder DesignTime, dan tidak disalin ke dalam aplikasi secara default. Sebagai gantinya, kamus sumber daya ini ada dalam memori sebagai bagian dari Windows Runtime itu sendiri, dan referensi sumber daya XAML aplikasi Anda ke sumber daya tema (atau sumber daya sistem) diselesaikan di sana pada runtime.

Panduan untuk sumber daya tema kustom

Ikuti panduan ini saat Anda menentukan dan menggunakan sumber daya tema kustom Anda sendiri:

  • Tentukan kamus tema untuk kamus "Terang" dan "Gelap" selain kamus "HighContrast" Anda. Meskipun Anda dapat membuat ResourceDictionary dengan "Default" sebagai kunci, lebih disukai untuk menjadi eksplisit dan sebaliknya menggunakan "Terang", "Gelap", dan "HighContrast".

  • Gunakan ekstensi markup {ThemeResource} di: Gaya, Setter, Templat kontrol, Setter properti, dan Animasi.

  • Jangan gunakan ekstensi markup {ThemeResource} dalam definisi sumber daya Anda di dalam ThemeDictionaries Anda. Gunakan ekstensi markup {StaticResource} sebagai gantinya.

    PENGECUALIAN: Anda dapat menggunakan ekstensi markup {ThemeResource} untuk mereferensikan sumber daya yang agnostik ke tema aplikasi di ThemeDictionaries Anda. Contoh sumber daya ini adalah sumber daya warna aksen seperti SystemAccentColor, atau sumber daya warna sistem, yang biasanya diawali dengan "SystemColor" seperti SystemColorButtonFaceColor.

Perhatian

Jika Anda tidak mengikuti panduan ini, Anda mungkin melihat perilaku tak terduga yang terkait dengan tema di aplikasi Anda. Untuk informasi selengkapnya, lihat bagian Pemecahan masalah sumber daya tema.

Ramp warna XAML dan kuas tergantung tema

Kumpulan warna gabungan untuk tema "Terang", "Gelap", dan "HighContrast" membentuk tanjakan warna Windows di XAML. Apakah Anda ingin memodifikasi tema sistem, atau menerapkan tema ke elemen XAML Anda sendiri, penting untuk memahami bagaimana sumber daya warna disusun.

Untuk informasi tambahan tentang cara menerapkan warna di aplikasi Windows Anda, silakan lihat Warna di aplikasi Windows.

Warna tema Terang dan Gelap

Kerangka kerja XAML menyediakan sekumpulan sumber daya Warna bernama dengan nilai yang disesuaikan untuk tema "Terang" dan "Gelap". Untuk WinUI 2, sumber daya tema didefinisikan dalam file Xaml sumber daya tema Umum. Nama warna sangat deskriptif dari penggunaan yang dimaksudkan, dan ada sumber daya SolidColorBrush yang sesuai untuk setiap sumber daya Warna.

Tip

Untuk gambaran umum visual warna-warna ini, lihat aplikasi Galeri WinUI 3: Warna

Aplikasi Galeri WinUI 3 mencakup contoh interaktif dari sebagian besar kontrol, fitur, dan fungsi WinUI 3. Dapatkan aplikasi dari Microsoft Store atau dapatkan kode sumber di GitHub

Warna tema kontras sistem Windows

Selain set sumber daya yang disediakan oleh kerangka kerja XAML, ada serangkaian nilai warna yang berasal dari palet sistem Windows. Warna-warna ini tidak spesifik untuk aplikasi Windows Runtime atau Windows. Namun, banyak sumber daya XAML Brush menggunakan warna-warna ini ketika sistem beroperasi (dan aplikasi sedang berjalan) menggunakan tema "HighContrast". Kerangka kerja XAML menyediakan warna di seluruh sistem ini sebagai sumber daya utama. Kunci mengikuti format penamaan: SystemColor[name]Color.

Untuk informasi selengkapnya tentang mendukung tema kontras, lihat Tema kontras.

Warna aksen sistem

Selain warna tema kontras sistem, warna aksen sistem disediakan sebagai sumber daya warna khusus menggunakan kunci SystemAccentColor. Pada runtime, sumber daya ini mendapatkan warna yang telah ditentukan pengguna sebagai warna aksen dalam pengaturan personalisasi Windows.

Catatan

Meskipun mungkin untuk mengambil alih sumber daya warna sistem, ini adalah praktik terbaik untuk menghormati pilihan warna pengguna, terutama untuk pengaturan tema kontras.

Kuas yang bergantung pada tema

Sumber daya warna yang ditunjukkan di bagian sebelumnya digunakan untuk mengatur properti Warna sumber daya SolidColorBrush dalam kamus sumber daya tema sistem. Anda menggunakan sumber daya kuas untuk menerapkan warna ke elemen XAML.

Mari kita lihat bagaimana nilai warna untuk kuas ini ditentukan pada run-time. Dalam kamus sumber daya "Terang" dan "Gelap", kuas ini didefinisikan seperti ini:

<SolidColorBrush x:Key="TextFillColorPrimaryBrush" Color="{StaticResource TextFillColorPrimary}"/>

Dalam kamus sumber daya "HighContrast", kuas ini didefinisikan seperti ini:

<SolidColorBrush x:Key="TextFillColorPrimaryBrush" Color="{ThemeResource SystemColorWindowTextColor}"/>

Ketika kuas ini diterapkan ke elemen XAML, warnanya ditentukan pada run-time oleh tema saat ini, seperti yang ditunjukkan dalam tabel ini.

Theme Sumber daya warna Nilai runtime
Ringan TextFillColorPrimary #E4000000
Gelap TextFillColorPrimary #FFFFFFFF
HighContrast SystemColorWindowTextColor Warna yang ditentukan dalam pengaturan untuk Teks.

Ramp jenis XAML

File themeresources.xaml menentukan beberapa sumber daya yang menentukan Gaya yang dapat Anda terapkan ke kontainer teks di UI Anda, khusus untuk TextBlock atau RichTextBlock. Ini bukan gaya implisit default. Mereka disediakan untuk memudahkan Anda membuat definisi UI XAML yang cocok dengan ramp jenis Windows yang didokumenkan dalam Panduan untuk font.

Gaya ini adalah untuk atribut teks yang ingin Anda terapkan ke seluruh kontainer teks. Jika Anda ingin gaya diterapkan hanya ke bagian teks, atur atribut pada elemen teks dalam kontainer, seperti pada Jalankan di TextBlock.Inlines atau pada Paragraf di RichTextBlock.Blocks.

Gaya terlihat seperti ini saat diterapkan ke TextBlock:

text block styles

Gaya Beban Ukuran
Keterangan Reguler 12
Isi Reguler 14
Tubuh Kuat {i>Semibold 14
Isi Besar Reguler 18
Subtitel {i>Semibold 20
Judul {i>Semibold 28
Judul Besar {i>Semibold 40
Tampilan {i>Semibold 68
<TextBlock Text="Caption" Style="{StaticResource CaptionTextBlockStyle}"/>
<TextBlock Text="Body" Style="{StaticResource BodyTextBlockStyle}"/>
<TextBlock Text="Body Strong" Style="{StaticResource BodyStrongTextBlockStyle}"/>
<TextBlock Text="Body Large" Style="{StaticResource BodyLargeTextBlockStyle}"/>
<TextBlock Text="Subtitle" Style="{StaticResource SubtitleTextBlockStyle}"/>
<TextBlock Text="Title" Style="{StaticResource TitleTextBlockStyle}"/>
<TextBlock Text="Title Large" Style="{StaticResource TitleLargeTextBlockStyle}"/>
<TextBlock Text="Display" Style="{StaticResource DisplayTextBlockStyle}"/>

Untuk panduan tentang cara menggunakan ramp jenis Windows di aplikasi Anda, lihat Tipografi di aplikasi Windows.

Untuk detail gaya XAML, lihat WinUI di GitHub:

Tip

Untuk gambaran umum visual gaya ini, lihat aplikasi Galeri WinUI 3: Tipografi

BaseRichTextBlockStyle

TargetType: RichTextBlock

Menyediakan properti umum untuk semua gaya kontainer RichTextBlock lainnya.

<!-- Usage -->
<RichTextBlock Style="{StaticResource BaseRichTextBlockStyle}">
    <Paragraph>Rich text.</Paragraph>
</RichTextBlock>

<!-- Style definition -->
<Style x:Key="BaseRichTextBlockStyle" TargetType="RichTextBlock">
    <Setter Property="FontFamily" Value="Segoe UI"/>
    <Setter Property="FontWeight" Value="SemiBold"/>
    <Setter Property="FontSize" Value="14"/>
    <Setter Property="TextTrimming" Value="None"/>
    <Setter Property="TextWrapping" Value="Wrap"/>
    <Setter Property="LineStackingStrategy" Value="MaxHeight"/>
    <Setter Property="TextLineBounds" Value="Full"/>
    <Setter Property="OpticalMarginAlignment" Value="TrimSideBearings"/>
</Style>

BodyRichTextBlockStyle

<!-- Usage -->
<RichTextBlock Style="{StaticResource BodyRichTextBlockStyle}">
    <Paragraph>Rich text.</Paragraph>
</RichTextBlock>

<!-- Style definition -->
<Style x:Key="BodyRichTextBlockStyle" TargetType="RichTextBlock" BasedOn="{StaticResource BaseRichTextBlockStyle}">
    <Setter Property="FontWeight" Value="Normal"/>
</Style>

Catatan: Gaya RichTextBlock tidak memiliki semua gaya ramp teks yang dilakukan TextBlock , terutama karena model objek dokumen berbasis blok untuk RichTextBlock memudahkan untuk mengatur atribut pada elemen teks individual. Selain itu, mengatur TextBlock.Text menggunakan properti konten XAML memperkenalkan situasi di mana tidak ada elemen teks untuk ditata dan dengan demikian Anda harus menata kontainer. Itu bukan masalah untuk RichTextBlock karena konten teksnya selalu harus berada dalam elemen teks tertentu seperti Paragraf, di mana Anda mungkin menerapkan gaya XAML untuk header halaman, subheader halaman, dan definisi ramp teks serupa.

Gaya Bernama Lain-lain

Ada sekumpulan definisi Gaya bertanda kunci tambahan yang dapat Anda terapkan untuk menata Tombol secara berbeda dari gaya implisit defaultnya.

TargetType: Tombol

Gaya ini menyediakan templat lengkap untuk Tombol yang bisa menjadi tombol navigasi kembali untuk aplikasi navigasi. Dimensi defaultnya adalah 40 x 40 piksel. Untuk menyesuaikan gaya, Anda dapat secara eksplisit mengatur properti Tinggi, Lebar, FontSize, dan properti lainnya pada Tombol Anda atau membuat gaya turunan menggunakan BasedOn.

Berikut adalah Tombol dengan sumber daya NavigationBackButtonNormalStyle yang diterapkan padanya.

<Button Style="{StaticResource NavigationBackButtonNormalStyle}" />

Terlihat seperti di bawah ini:

A button styled as a back button

TargetType: Tombol

Gaya ini menyediakan templat lengkap untuk Tombol yang bisa menjadi tombol navigasi kembali untuk aplikasi navigasi. Ini mirip dengan NavigationBackButtonNormalStyle, tetapi dimensinya adalah 30 x 30 piksel.

Berikut adalah Tombol dengan sumber daya NavigationBackButtonSmallStyle yang diterapkan padanya.

<Button Style="{StaticResource NavigationBackButtonSmallStyle}" />

Pemecahan masalah sumber daya tema

Jika Anda tidak mengikuti panduan untuk menggunakan sumber daya tema, Anda mungkin melihat perilaku tak terduga yang terkait dengan tema di aplikasi Anda.

Misalnya, saat Anda membuka flyout bertema terang, bagian aplikasi bertema gelap Anda juga berubah seolah-olah mereka berada dalam tema terang. Atau jika Anda menavigasi ke halaman bertema terang dan kemudian menavigasi kembali, halaman bertema gelap asli (atau bagiannya) sekarang terlihat seolah-olah berada dalam tema terang.

Biasanya, jenis masalah ini terjadi saat Anda menyediakan tema "Default" dan tema "HighContrast" untuk mendukung skenario kontras tinggi, lalu menggunakan tema "Terang" dan "Gelap" di berbagai bagian aplikasi Anda.

Misalnya, pertimbangkan definisi kamus tema ini:

<!-- DO NOT USE. THIS XAML DEMONSTRATES AN ERROR. -->
<ResourceDictionary>
  <ResourceDictionary.ThemeDictionaries>
    <ResourceDictionary x:Key="Default">
      <SolidColorBrush x:Key="myBrush" Color="{ThemeResource ControlFillColorDefault}"/>
    </ResourceDictionary>
    <ResourceDictionary x:Key="HighContrast">
      <SolidColorBrush x:Key="myBrush" Color="{ThemeResource SystemColorButtonFaceColor}"/>
    </ResourceDictionary>
  </ResourceDictionary.ThemeDictionaries>
</ResourceDictionary>

Secara intuitif, ini terlihat benar. Anda ingin mengubah warna yang ditujukan pada myBrush saat kontras tinggi, tetapi ketika tidak berkontras tinggi, Anda mengandalkan ekstensi markup {ThemeResource} untuk memastikan bahwa myBrush menunjuk ke warna yang tepat untuk tema Anda. Jika aplikasi Anda tidak pernah memiliki FrameworkElement.RequestedTheme yang diatur pada elemen dalam pohon visualnya, ini biasanya akan berfungsi seperti yang diharapkan. Namun, Anda mengalami masalah di aplikasi segera setelah mulai membuat tema ulang berbagai bagian pohon visual Anda.

Masalah terjadi karena kuas adalah sumber daya bersama, tidak seperti kebanyakan jenis XAML lainnya. Jika Anda memiliki 2 elemen di sub-pohon XAML dengan tema berbeda yang mereferensikan sumber daya kuas yang sama, maka karena kerangka kerja memandu setiap sub-pohon untuk memperbarui ekspresi ekstensi markup {ThemeResource}, perubahan pada sumber daya kuas bersama tercermin di sub-pohon lain, yang bukan hasil yang Anda maksudkan.

Untuk memperbaiki ini, ganti kamus "Default" dengan kamus tema terpisah untuk tema "Terang" dan "Gelap" selain "HighContrast":

<!-- DO NOT USE. THIS XAML DEMONSTRATES AN ERROR. -->
<ResourceDictionary>
  <ResourceDictionary.ThemeDictionaries>
    <ResourceDictionary x:Key="Light">
      <SolidColorBrush x:Key="myBrush" Color="{ThemeResource ControlFillColorDefault}"/>
    </ResourceDictionary>
    <ResourceDictionary x:Key="Dark">
      <SolidColorBrush x:Key="myBrush" Color="{ThemeResource ControlFillColorDefault}"/>
    </ResourceDictionary>
    <ResourceDictionary x:Key="HighContrast">
      <SolidColorBrush x:Key="myBrush" Color="{ThemeResource SystemColorButtonFaceColor}"/>
    </ResourceDictionary>
  </ResourceDictionary.ThemeDictionaries>
</ResourceDictionary>

Namun, masalah masih terjadi jika salah satu sumber daya ini direferensikan dalam properti yang diwariskan seperti Latar Depan. Templat kontrol kustom Anda mungkin menentukan warna latar depan elemen menggunakan ekstensi markup {ThemeResource}, tetapi ketika kerangka kerja menyebarluaskan nilai yang diwariskan ke elemen turunan, ia menyediakan referensi langsung ke sumber daya yang diselesaikan oleh ekspresi ekstensi markup {ThemeResource}. Ini menyebabkan masalah ketika kerangka kerja memproses tema berubah saat berjalan di pohon visual kontrol Anda. Ini mengevaluasi kembali ekspresi ekstensi markup {ThemeResource} untuk mendapatkan sumber daya kuas baru tetapi belum menyebarluaskan referensi ini ke turunan kontrol Anda; ini terjadi nanti, seperti selama lulus ukuran berikutnya.

Akibatnya, setelah menjalankan pohon visual kontrol sebagai respons terhadap perubahan tema, kerangka kerja memandu anak-anak dan memperbarui ekspresi ekstensi markup {ThemeResource} yang diatur pada mereka, atau pada objek yang diatur pada propertinya. Di sinilah masalah terjadi; kerangka kerja memandu sumber daya kuas dan karena menentukan warnanya menggunakan ekstensi markup {ThemeResource}, maka akan dievaluasi ulang.

Pada titik ini, kerangka kerja tampaknya telah mencemari kamus tema Anda karena sekarang memiliki sumber daya dari satu kamus yang memiliki set warna dari kamus lain.

Untuk memperbaiki masalah ini, gunakan ekstensi markup {StaticResource} alih-alih ekstensi markup {ThemeResource}. Dengan pedoman yang diterapkan, kamus tema terlihat seperti ini:

<ResourceDictionary>
  <ResourceDictionary.ThemeDictionaries>
    <ResourceDictionary x:Key="Light">
      <SolidColorBrush x:Key="myBrush" Color="{StaticResource ControlFillColorDefault}"/>
    </ResourceDictionary>
    <ResourceDictionary x:Key="Dark">
      <SolidColorBrush x:Key="myBrush" Color="{StaticResource ControlFillColorDefault}"/>
    </ResourceDictionary>
    <ResourceDictionary x:Key="HighContrast">
      <SolidColorBrush x:Key="myBrush" Color="{ThemeResource SystemColorButtonFaceColor}"/>
    </ResourceDictionary>
  </ResourceDictionary.ThemeDictionaries>
</ResourceDictionary>

Perhatikan bahwa ekstensi markup {ThemeResource} masih digunakan dalam kamus "HighContrast" alih-alih ekstensi markup {StaticResource}. Situasi ini termasuk dalam pengecualian yang diberikan sebelumnya dalam pedoman. Sebagian besar nilai sikat yang digunakan untuk tema "HighContrast" menggunakan pilihan warna yang dikontrol secara global oleh sistem, tetapi diekspos ke XAML sebagai sumber daya bernama khusus (yang diawali dengan 'SystemColor' dalam namanya). Sistem memungkinkan pengguna untuk mengatur warna tertentu yang harus digunakan untuk pengaturan tema kontras mereka melalui Pusat Kemudahan Akses. Pilihan warna tersebut diterapkan ke sumber daya bernama khusus. Kerangka kerja XAML menggunakan peristiwa perubahan tema yang sama untuk juga memperbarui kuas ini ketika mendeteksi bahwa mereka telah berubah di tingkat sistem. Inilah sebabnya mengapa ekstensi markup {ThemeResource} digunakan di sini.