Prostředky téma XAML

Prostředky motivu v XAML jsou sada prostředků, které používají různé hodnoty v závislosti na tom, který systémový motiv je aktivní. Existují tři motivy, které architektura XAML podporuje: "Light", "Dark" a "HighContrast".

Požadavky: Toto téma předpokládá, že jste si přečetli odkazy na prostředky ResourceDictionary a XAML.

Zdroje motivů vs. statické prostředky

Existují dvě rozšíření značkovacího jazyka XAML, která mohou odkazovat na prostředek XAML z existujícího slovníku prostředků XAML: rozšíření značkovacího jazyka {StaticResource} a rozšíření značkovacího jazyka {ThemeResource}.

Vyhodnocení rozšíření značek {ThemeResource} probíhá, když se aplikace načte a následně pokaždé, když se motiv změní během spuštění. Obvykle se jedná o výsledek změny nastavení zařízení uživatele nebo programové změny v aplikaci, která mění aktuální motiv.

Naproti tomu se rozšíření značek {StaticResource} vyhodnocuje jenom, když aplikace poprvé načte XAML. Neaktualizuje se. Podobá se vyhledání a nahrazení v XAML skutečnou hodnotou modulu runtime při spuštění aplikace.

Prostředky tématu ve struktuře slovníku prostředků

Každý motivový prostředek je součástí souboru XAML themeresources.xaml. Pro účely návrhu je soubor themeresources.xaml dostupný ve složce \(Program Files)\Windows Kits\10\DesignTime\CommonConfiguration\Neutral\UAP\<SDK version>\Generic z instalace sady Windows Software Development Kit (SDK). Zdrojové slovníky v themeresources.xaml jsou také zahrnuty v generic.xaml ve stejném adresáři.

Windows Runtime tyto fyzické soubory nepoužívá pro vyhledávání za běhu. Proto jsou konkrétně ve složce DesignTime a ve výchozím nastavení se do aplikací nekopírují. Místo toho tyto slovníky prostředků existují v paměti jako součást samotného Windows Runtime a odkazy na prostředky XAML vaší aplikace na prostředky motivu (nebo systémové prostředky) se tam za běhu přeloží.

Pokyny pro vlastní zdroje tématu

Při definování a využívání vlastních prostředků tématu postupujte podle těchto doporučení:

Upozornění

Pokud tyto pokyny nedodržujete, může se zobrazit neočekávané chování související s motivy ve vaší aplikaci. Další informace najdete v oddílu Řešení potíží s prostředky motivu.

Barevná rampa XAML a štětce závislé na motivu

Kombinovaná sada barev pro motivy "Světlo", "Tmavá" a "HighContrast" tvoří barevnou rampu Windows v XAML. Bez ohledu na to, jestli chcete upravit systémové motivy nebo použít motiv na vlastní prvky XAML, je důležité pochopit, jak jsou barevné prostředky strukturované.

Další informace o použití barvy v Windows app najdete v tématu Color v aplikacích pro Windows.

Světlé a tmavé barvy motivu

Architektura XAML poskytuje sadu pojmenovaných prostředků Color s hodnotami, které jsou přizpůsobené motivům "Světlý" a "Tmavý". V případě WinUI jsou prostředky motivu definovány ve souboru XAML společných prostředků motivu. Názvy barev jsou velmi popisné pro jejich zamýšlené použití a pro každý zdroj barvy je k dispozici odpovídající zdroj SolidColorBrush.

Návod

Vizuální přehled těchto barev najdete v aplikaci Galerie WinUI 3: Barvy

Aplikace Galerie WinUI 3 obsahuje interaktivní příklady většiny ovládacích prvků, funkcí a funkcí WinUI. Získejte aplikaci z Microsoft Store nebo získejte zdrojový kód na GitHub

Barvy kontrastního motivu systému Windows

Kromě sady prostředků poskytovaných architekturou XAML existuje sada barevných hodnot odvozených ze systémové palety Systému Windows. Tyto barvy nejsou specifické pro Windows Runtime ani aplikace pro Windows. Mnoho prostředků XAML štětce však tyto barvy spotřebovává, když systém pracuje (a aplikace běží) s motivem Vysoký Kontrast. Architektura XAML poskytuje tyto systémové barvy jako klíčové prostředky. Klíče se řídí formátem pojmenování: SystemColor[name]Color.

Další informace o podpoře motivů kontrastu naleznete v tématu Kontrastní motivy.

Barva zvýraznění systému

Kromě barev motivu kontrastu systému je barva zvýraznění systému poskytována jako speciální barva pomocí klíče SystemAccentColor. Za běhu získá tento prostředek barvu, kterou uživatel zadal jako barvu zvýraznění v nastavení přizpůsobení Systému Windows.

Poznámka:

I když je možné přepsat systémové barevné prostředky, je osvědčeným postupem respektovat volby barev uživatele, zejména pro nastavení kontrastu motivu.

Štětce závislé na tématu

Barevné prostředky zobrazené v předchozích částech slouží k nastavení vlastnosti Color prostředků SolidColorBrush ve slovníkech prostředků systémového motivu. Pro aplikaci barvy na prvky XAML se využívají zdroje štětce.

Pojďme se podívat, jak se v době běhu programu určuje barva tohoto štětce. Ve slovnících zdrojů Light a Dark je tento štětec definován takto:

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

Ve slovníku prostředků HighContrast je tento štětec definován takto:

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

Při použití tohoto štětce u elementu XAML se jeho barva určuje za běhu aktuálním motivem, jak je znázorněno v této tabulce.

Theme Barevný zdroj Hodnota modulu runtime
Light BarvaVyplněnéhoTextuPrimární #E4000000
Temný BarvaVyplněnéhoTextuPrimární #FFFFFFFF
HighContrast SystemColorWindowTextColor Barva zadaná v nastavení pro text.

Rampa typu XAML

Soubor themeresources.xaml definuje několik prostředků, které definují styl , který můžete použít u textových kontejnerů v uživatelském rozhraní, konkrétně pro TextBlock nebo RichTextBlock. Nejedná se o výchozí implicitní styly. Jsou k dispozici, abyste usnadnili vytváření definic uživatelského rozhraní XAML, které odpovídají rampě typu Windows popsané v pokynech pro písma.

Tyto styly jsou určené pro atributy textu, které chcete použít u celého textového kontejneru. Pokud chcete, aby se styly použily pouze u určitých částí textu, nastavte atributy na textových prvcích v kontejneru, například na Run v TextBlock.Inlines nebo na Paragraph v RichTextBlock.Blocks.

Styly vypadají takto, když se použijí na TextBlock:

Styly bloku textu

Styl Weight Velikost
Titulek Pravidelný 12
Body Pravidelný 14
Silné tělo Středník 14
Velké tělo Pravidelný 18
Tělo velké a silné Středník 18
Podtitul Středník 20
Title Středník 28
Velký název Středník 40
Display Středník 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="Body Large Strong" Style="{StaticResource BodyLargeStrongTextBlockStyle}"/>
<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}"/>

Pokyny k používání rampy typu Windows v aplikaci najdete v tématu Typografie v aplikacích pro Windows.

Podrobnosti o stylech XAML najdete v tématu WinUI na GitHub:

Návod

Vizuální přehled těchto stylů najdete v aplikaci Galerie WinUI 3: Typografie

BaseRichTextBlockStyle

TargetType: RichTextBlock

Poskytuje společné vlastnosti pro všechny ostatní styly kontejneru RichTextBlock .

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

<!-- Style definition -->
<Style x:Key="BaseRichTextBlockStyle" TargetType="RichTextBlock">
    <Setter Property="FontFamily" Value="Segoe UI Variable"/>
    <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>

Poznámka: Styly RichTextBlock nemají všechny styly textové rampy, které TextBlock dělá, zejména proto, že model objektu dokumentu založené na bloku pro RichTextBlock usnadňuje nastavení atributů u jednotlivých textových prvků. Nastavení TextBlock.Text pomocí vlastnosti obsahu XAML také představuje situaci, kdy neexistuje žádný textový prvek k naformátování, a proto byste museli stylistizovat kontejner. To není problém pro RichTextBlock, protože jeho textový obsah musí být vždy v konkrétních textových prvcích, jako je Odstavec, kde můžete použít styly XAML pro záhlaví stránky, podzáhlaví stránky a podobné definice textových ramp.

Různé pojmenované styly

Existuje další sada definic klíčových stylů , které můžete použít pro styl tlačítka jinak než výchozí implicitní styl.

TargetType: Button

Tento styl poskytuje úplnou šablonu pro tlačítko , které může být navigačním tlačítkem zpět pro navigační aplikaci. Výchozí rozměry jsou 40 x 40 pixelů. Pokud chcete styl přizpůsobit, můžete buď explicitně nastavit Výšku, Šířku, PísmoSize a další vlastnosti tlačítka, nebo vytvořit odvozený styl pomocí BasedOn.

Tady je tlačítko s aplikovaným zdrojem NavigationBackButtonNormalStyle.

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

Vypadá takto:

Tlačítko stylované jako tlačítko Zpět

TargetType: Button

Tento styl poskytuje úplnou šablonu pro tlačítko , které může být navigačním tlačítkem zpět pro navigační aplikaci. Podobá se NavigationBackButtonNormalStyle, ale jeho rozměry jsou 30 x 30 pixelů.

Tady je tlačítko s aplikovaným stylem NavigationBackButtonSmallStyle.

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

Řešení problémů se zdroji motivu

Pokud nedodržujete pokyny pro používání prostředků motivu, ve vaší aplikaci se může objevit neočekávané chování související s motivy.

Když například otevřete vyskakovací okno se světlým motivem, části vaší aplikace s tmavým motivem se také změní, jako by byly ve světlém motivu. Nebo pokud přejdete na světle motivovanou stránku a pak se vrátíte zpět, původní tmavě motivovaná stránka (nebo jeho části) teď vypadá, jako by byla ve světlém motivu.

K těmto typům problémů obvykle dochází, když zadáte "výchozí" motiv a motiv "HighContrast", který podporuje scénáře s vysokým kontrastem, a pak použijete motivy "Světlý" i "Tmavý" v různých částech vaší aplikace.

Představte si například tuto definici slovníku motivů:

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

Intuitivně to vypadá správně. Chcete změnit barvu označenou myBrush při vysokém kontrastu. Když není ve vysokém kontrastu, spoléháte na rozšíření značek {ThemeResource}, abyste zajistili, že myBrush odkazuje na správnou barvu pro váš motiv. Pokud vaše aplikace nikdy nemá FrameworkElement.RequestedTheme nastaven na elementy ve svém vizuálním stromu, bude to obvykle fungovat podle očekávání. Jakmile ale začnete různé části vizuálního stromu přetémovat, narazíte na problémy ve své aplikaci.

K tomuto problému dochází, protože štětce jsou sdílené prostředky, což je odlišné od většiny ostatních typů XAML. Pokud máte v dílčích stromech XAML 2 prvky s různými motivy, které odkazují na stejný prostředek štětce, pak rámec provede každý dílčí strom aktualizováním výrazů rozšíření značek {ThemeResource}, změny prostředku sdíleného štětce se projeví v druhém dílčím stromu, což není váš zamýšlený výsledek.

Pokud chcete tento problém vyřešit, nahraďte slovník výchozího motivu samostatnými slovníky motivu pro motivy "Světlý" i "Tmavý" kromě "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>

Nicméně problémy stále nastávají, pokud některé z těchto prostředků jsou odkazovány ve zděděných vlastnostech, jako Foreground. Šablona vlastního ovládacího prvku může určit barvu popředí prvku pomocí rozšíření značek {ThemeResource}, ale když architektura rozšíří zděděnou hodnotu do podřízených prvků, poskytuje přímý odkaz na prostředek, který byl vyřešen výrazem rozšíření značek {ThemeResource}. To způsobuje problémy, když framework zpracovává změny motivu během procházení vizuálním stromem vašeho ovládacího prvku. Znovu přehodnotí výraz rozšíření značky {ThemeResource}, aby získal nový prostředek štětce, a zatím tento odkaz nerozšířuje na podřízené položky vašeho ovládacího prvku; k tomu dojde později, například během dalšího průchodu měření.

Výsledkem je, že po procházení vizuálního stromu ovládacího prvku v reakci na změnu motivu architektura projde podřízené položky a aktualizuje všechny výrazy rozšíření značek {ThemeResource} nastavené na ně, nebo na objekty nastavené na jejich vlastnosti. To je místo, kde k problému dochází; framework prochází prostředkem štětce a protože určuje jeho barvu pomocí markup rozšíření {ThemeResource}, je znovu vyhodnocen.

V tuto chvíli se zdá, že rámec narušil slovník motivu, protože nyní obsahuje prostředek z jednoho slovníku, jehož barva je nastavena z jiného slovníku.

Pokud chcete tento problém vyřešit, použijte místo rozšíření značení {ThemeResource}rozšíření značení {StaticResource}. S použitými pokyny vypadají slovníky motivu takto:

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

Všimněte si, že rozšíření značek {ThemeResource} se stále používá ve slovníku HighContrast místo rozšíření značek {StaticResource}. Tato situace spadá do výjimky uvedené výše v pokynech. Většina hodnot štětců používaných pro motiv "HighContrast" využívá barevné volby, které jsou globálně řízeny systémem, ale jsou zpřístupněny pro XAML jako speciálně pojmenovaný prostředek (ty, které mají v názvu předponu SystemColor). Systém umožňuje uživateli nastavit konkrétní barvy, které by se měly použít pro nastavení kontrastního motivu prostřednictvím Centra usnadnění Access. Tyto volby barev jsou aplikovány na speciálně pojmenované prostředky. Architektura XAML používá stejnou událost změny motivu k aktualizaci těchto štětců, když zjistí, že se změnily na úrovni systému. Proto je zde použito rozšíření značek {ThemeResource}.