Delen via


XAML-themabronnen

Themabronnen in XAML zijn een set resources die verschillende waarden toepassen, afhankelijk van het systeemthema dat actief is. Er zijn drie thema's die door het XAML-framework worden ondersteund: 'Licht', 'Donker' en 'HighContrast'.

Vereisten: in dit onderwerp wordt ervan uitgegaan dat u resourcedictionary- en XAML-resourceverwijzingen hebt gelezen.

Themabronnen v. statische resources

Er zijn twee XAML-markeringsextensies die kunnen verwijzen naar een XAML-resource uit een bestaande XAML-resourcewoordenlijst: de markeringsextensie {StaticResource} en de markeringsextensie {ThemeResource}.

Evaluatie van een markeringsextensie {ThemeResource} vindt plaats wanneer de app wordt geladen en vervolgens telkens wanneer het thema tijdens runtime wordt gewijzigd. Dit is meestal het resultaat van het wijzigen van hun apparaatinstellingen of van een programmatische wijziging in de app die het huidige thema wijzigt.

Daarentegen wordt een markeringsextensie {StaticResource} alleen geëvalueerd wanneer de XAML voor het eerst door de app wordt geladen. Het wordt niet bijgewerkt. Het is vergelijkbaar met een zoek- en vervangingswaarde in uw XAML door de werkelijke runtimewaarde bij het starten van de app.

Themaresources in de resourcewoordenlijststructuur

Elke themaresource maakt deel uit van het XAML-bestand themeresources.xaml. Voor ontwerpdoeleinden is themeresources.xaml beschikbaar in de map \(Program Files)\Windows Kits\10\DesignTime\CommonConfiguration\Neutral\UAP\<SDK version>\Generic van een Installatie van een Windows Software Development Kit (SDK). De resourcewoordenlijsten in themeresources.xaml worden ook gereproduceerd in generic.xaml in dezelfde map.

Windows Runtime gebruikt deze fysieke bestanden niet voor runtimezoekacties. Daarom bevinden ze zich specifiek in een DesignTime-map en worden ze niet standaard gekopieerd naar apps. In plaats daarvan bestaan deze resourcewoordenlijsten in het geheugen als onderdeel van de Windows Runtime zelf en worden de XAML-resourceverwijzingen van uw app naar themaresources (of systeemresources) daar tijdens runtime omgezet.

Richtlijnen voor aangepaste themaresources

Volg deze richtlijnen wanneer u uw eigen aangepaste themaresources definieert en gebruikt:

Waarschuwing

Als u deze richtlijnen niet volgt, ziet u mogelijk onverwacht gedrag met betrekking tot thema's in uw app. Zie de sectie Problemen met themaresources oplossen voor meer informatie.

De XAML-kleur ramp en themaafhankelijke borstels

De gecombineerde set kleuren voor de thema's 'Licht', 'Donker' en 'HighContrast' vormen de Windows-kleurenplaat in XAML. Of u nu de systeemthema's wilt wijzigen of een thema wilt toepassen op uw eigen XAML-elementen, het is belangrijk om te begrijpen hoe de kleurbronnen zijn gestructureerd.

Zie Kleur in Windows-apps voor meer informatie over het toepassen van kleur in uw Windows-app.

Lichte en donkere themakleuren

Het XAML-framework biedt een set benoemde kleurbronnen met waarden die zijn afgestemd op de thema's Licht en Donker. Voor WinUI 2 worden de themabronnen gedefinieerd in het bestand Algemene themabronnen Xaml. De kleurnamen zijn zeer beschrijvend voor hun beoogde gebruik en er is een bijbehorende SolidColorBrush-resource voor elke kleurresource.

Aanbeveling

Zie de WinUI 3 Gallery-app voor een visueel overzicht van deze kleuren: Kleuren

De WinUI 3 Gallery-app bevat interactieve voorbeelden van de meeste Besturingselementen, functies en functionaliteit van WinUI 3. Haal de app op uit de Microsoft Store of haal de broncode op GitHub op

Themakleuren voor Windows-systeemcontrast

Naast de set resources die worden geleverd door het XAML-framework, is er een set kleurwaarden die zijn afgeleid van het Windows-systeempalet. Deze kleuren zijn niet specifiek voor de Windows Runtime- of Windows-apps. Veel van de XAML Brush-resources gebruiken deze kleuren echter wanneer het systeem wordt uitgevoerd (en de app wordt uitgevoerd) met behulp van het thema HighContrast. Het XAML-framework biedt deze systeembrede kleuren als belangrijke resources. De sleutels volgen de naamgevingsindeling: SystemColor[name]Color.

Zie Contrastthema's voor meer informatie over het ondersteunen van contrastthema's.

Systeemaccentkleur

Naast de kleuren van het systeemcontrastthema wordt de kleur van het systeemaccent geleverd als een speciale kleurresource met behulp van de sleutel SystemAccentColor. Tijdens runtime haalt deze resource de kleur op die de gebruiker heeft opgegeven als de accentkleur in de instellingen voor persoonlijke instellingen van Windows.

Opmerking

Hoewel het mogelijk is om de systeemkleurbronnen te overschrijven, is het een best practice om de kleurkeuzes van de gebruiker te respecteren, met name voor instellingen voor contrastthema's.

Themaafhankelijke borstels

De kleurresources die in de voorgaande secties worden weergegeven, worden gebruikt om de eigenschap Color van SolidColorBrush-resources in te stellen in de resourcewoordenlijsten voor systeemthema's. U gebruikt de kwastbronnen om de kleur toe te passen op XAML-elementen.

Laten we eens kijken hoe de kleurwaarde voor deze borstel tijdens runtime wordt bepaald. In de bronwoordenlijsten 'Licht' en 'Donker' wordt deze kwast als volgt gedefinieerd:

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

In de resourcewoordenlijst HighContrast wordt dit kwast als volgt gedefinieerd:

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

Wanneer deze borstel wordt toegepast op een XAML-element, wordt de kleur ervan bepaald tijdens de uitvoering door het huidige thema, zoals wordt weergegeven in deze tabel.

Theme Kleurresource Runtimewaarde
Light TextFillColorPrimary #E4000000
Donker TextFillColorPrimary #FFFFFFFF
HighContrast SystemColorWindowTextColor De kleur die is opgegeven in de instellingen voor Tekst.

De XAML-type ramp

Het bestand themeresources.xaml definieert verschillende resources die een stijl definiëren die u kunt toepassen op tekstcontainers in uw gebruikersinterface, met name voor TextBlock of RichTextBlock. Dit zijn niet de standaard impliciete stijlen. Ze zijn beschikbaar om het voor u gemakkelijker te maken om XAML UI-definities te maken die overeenkomen met de windows-type ramp die wordt beschreven in richtlijnen voor lettertypen.

Deze stijlen zijn bedoeld voor tekstkenmerken die u wilt toepassen op de hele tekstcontainer. Als u alleen stijlen wilt toepassen op secties van de tekst, stelt u kenmerken in op de tekstelementen in de container, zoals op een run in TextBlock.Inlines of op een alinea in RichTextBlock.Blocks.

De stijlen zien er als volgt uit wanneer ze worden toegepast op een TextBlock:

stijlen voor tekstblokken

Stijl Weight Grootte
Bijschrift Regelmatig 12
Body Regelmatig 14
Lichaam sterk Semibold 14
Hoofdtekst groot Regelmatig 18
Ondertitel Semibold 20
Title Semibold 28
Titel groot Semibold 40
Beeldscherm 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}"/>

Zie Typografie in Windows-apps voor hulp bij het gebruik van de ramp van het Windows-type in uw app.

Zie WinUI op GitHub voor meer informatie over de XAML-stijlen:

Aanbeveling

Zie de WinUI 3 Gallery-app: Typografie voor een visueel overzicht van deze stijlen

BaseRichTextBlockStyle

TargetType: RichTextBlock

Levert de algemene eigenschappen voor alle andere RichTextBlock-containerstijlen .

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

Opmerking: de RichTextBlock-stijlen hebben niet alle stijlen voor tekst ramps die Door TextBlock worden uitgevoerd, vooral omdat het op blok gebaseerde documentobjectmodel voor RichTextBlock het gemakkelijker maakt om kenmerken in te stellen voor de afzonderlijke tekstelementen. Als u TextBlock.Text instelt met behulp van de inhoudseigenschap XAML, ontstaat er een situatie waarin er geen tekstelement in stijl is en u de container dus moet stylen. Dat is geen probleem voor RichTextBlock , omdat de tekstinhoud altijd in specifieke tekstelementen moet staan, zoals Alinea. Hier kunt u XAML-stijlen toepassen voor paginakopteksten, paginasubheader en vergelijkbare definities voor tekst ramps.

Diverse benoemde stijlen

Er is een extra set sleutelstijldefinities die u op een knop kunt toepassen op een andere stijl dan de standaard impliciete stijl.

TargetType: knop

Deze stijl biedt een volledige sjabloon voor een knop die de knop Terug voor navigatie kan zijn voor een navigatie-app. De standaardafmetingen zijn 40 x 40 pixels. Als u de stijl wilt aanpassen, kunt u de eigenschappen Height, Width, FontSize en andere eigenschappen op de knop expliciet instellen of een afgeleide stijl maken met BasedOn.

Hier volgt een knop waarop de resource NavigationBackButtonNormalStyle is toegepast.

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

Het ziet er als volgt uit:

Een knop die is gestijld als een knop Vorige

TargetType: knop

Deze stijl biedt een volledige sjabloon voor een knop die de knop Terug voor navigatie kan zijn voor een navigatie-app. Het is vergelijkbaar met NavigationBackButtonNormalStyle, maar de afmetingen zijn 30 x 30 pixels.

Hier volgt een knop waarop de resource NavigationBackButtonSmallStyle is toegepast.

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

Problemen met themabronnen oplossen

Als u de richtlijnen voor het gebruik van themabronnen niet volgt, ziet u mogelijk onverwacht gedrag met betrekking tot thema's in uw app.

Wanneer u bijvoorbeeld een flyout met lichtthema opent, veranderen delen van uw donkere thema-app ook alsof ze zich in het lichtthema bevinden. Of als u naar een lichtgethemate pagina navigeert en vervolgens terug navigeert, ziet de oorspronkelijke donkere pagina (of delen ervan) er nu uit alsof deze zich in het lichtthema bevindt.

Normaal gesproken treden deze soorten problemen op wanneer u een standaardthema en een HighContrast-thema opgeeft ter ondersteuning van scenario's met hoog contrast en vervolgens zowel 'Licht' als 'Donker' thema's gebruikt in verschillende delen van uw app.

Denk bijvoorbeeld aan deze definitie van de themawoordenlijst:

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

Intuïtief ziet dit er correct uit. U wilt de kleur wijzigen waarnaar wordt verwezen myBrush in hoog contrast, maar wanneer u niet in hoog contrast bent, vertrouwt u op de markeringsextensie {ThemeResource} om ervoor te zorgen dat myBrush deze naar de juiste kleur voor uw thema verwijst. Als frameworkElement.RequestedTheme voor uw app nooit is ingesteld op elementen in de visuele structuur, werkt dit doorgaans zoals verwacht. U ondervindt echter problemen in uw app zodra u verschillende onderdelen van de visualstructuur opnieuw gaat thema's geven.

Het probleem treedt op omdat borstels gedeelde resources zijn, in tegenstelling tot de meeste andere XAML-typen. Als u twee elementen in XAML-substructuren hebt met verschillende thema's die verwijzen naar dezelfde kwastresource, worden wijzigingen in de gedeelde kwastresource weergegeven in de andere substructuur, wat niet het beoogde resultaat is.

U kunt dit oplossen door de woordenlijst 'Standaard' te vervangen door afzonderlijke themawoordenlijsten voor thema's 'Licht' en 'Donker' naast 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>

Er treden echter nog steeds problemen op als naar een van deze resources wordt verwezen in overgenomen eigenschappen, zoals Foreground. Uw aangepaste besturingselementsjabloon kan de voorgrondkleur van een element opgeven met behulp van de markeringsextensie {ThemeResource}, maar wanneer het framework de overgenomen waarde doorgeeft aan onderliggende elementen, biedt het een directe verwijzing naar de resource die is opgelost door de extensieexpressie {ThemeResource}. Dit veroorzaakt problemen wanneer het framework themawijzigingen verwerkt terwijl deze de visuele structuur van uw besturingselement doorloopt. De extensie-expressie {ThemeResource} wordt opnieuw geëvalueerd om een nieuwe kwastresource op te halen, maar deze verwijzing nog niet doorgegeven aan de onderliggende elementen van uw besturingselement; dit gebeurt later, bijvoorbeeld tijdens de volgende metingspas.

Als gevolg hiervan leidt het framework na het doorlopen van de visuele structuur van het besturingselement als reactie op een themawijziging de onderliggende elementen en werkt het framework alle expressies van de markeringsextensie {ThemeResource} die erop zijn ingesteld, bij of op objecten die zijn ingesteld op hun eigenschappen. Hier treedt het probleem op; het framework begeleidt de kwastresource en omdat deze de kleur aangeeft met behulp van een markeringsextensie {ThemeResource}, wordt deze opnieuw geëvalueerd.

Op dit moment lijkt het framework uw themawoordenlijst vervuild te hebben, omdat het nu een resource bevat uit de ene woordenlijst met de kleur die is ingesteld vanuit een andere woordenlijst.

U kunt dit probleem oplossen door de markeringsextensie {StaticResource} te gebruiken in plaats van de markeringsextensie {ThemeResource}. Wanneer de richtlijnen zijn toegepast, zien de themawoordenlijsten er als volgt uit:

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

U ziet dat de markeringsextensie {ThemeResource} nog steeds wordt gebruikt in de woordenlijst HighContrast in plaats van de markeringsextensie {StaticResource}. Deze situatie valt onder de uitzondering die eerder in de richtsnoeren is opgegeven. De meeste kwastwaarden die worden gebruikt voor het thema HighContrast, gebruiken kleurkeuzen die globaal worden beheerd door het systeem, maar worden blootgesteld aan XAML als een speciaal benoemde resource (die voorafgegaan worden door SystemColor in de naam). Met het systeem kan de gebruiker de specifieke kleuren instellen die moeten worden gebruikt voor hun contrastthema-instellingen via het Toegankelijkheidscentrum. Deze kleurkeuzen worden toegepast op de speciaal benoemde resources. In het XAML-framework wordt dezelfde gebeurtenis gebruikt om deze penselen ook bij te werken wanneer wordt gedetecteerd dat ze op systeemniveau zijn gewijzigd. Daarom wordt hier de markeringsextensie {ThemeResource} gebruikt.