Nuta
Dostęp do tej strony wymaga autoryzacji. Możesz spróbować się zalogować lub zmienić katalog.
Dostęp do tej strony wymaga autoryzacji. Możesz spróbować zmienić katalogi.
Zasoby motywu w języku XAML to zestaw zasobów, które stosują różne wartości w zależności od tego, który motyw systemowy jest aktywny. Istnieją 3 motywy obsługiwane przez strukturę XAML: "Light", "Dark" i "HighContrast".
Wymagania wstępne: w tym temacie założono, że znasz odwołania do zasobów ResourceDictionary i XAML.
Zasoby motywu v. zasoby statyczne
Istnieją dwa rozszerzenia znaczników XAML, które mogą odwoływać się do zasobu XAML z istniejącego słownika zasobów XAML: rozszerzenie znaczników {StaticResource} i rozszerzenie znaczników {ThemeResource}.
Ocena rozszerzenia znaczników {ThemeResource} odbywa się, gdy aplikacja ładuje się, a następnie za każdym razem, gdy motyw zmienia się w czasie wykonywania. Jest to zazwyczaj wynik zmiany ustawień urządzenia przez użytkownika lub zmiany programowej w aplikacji, która zmienia jego bieżący motyw.
Natomiast rozszerzenie znaczników {StaticResource} jest oceniane tylko wtedy, gdy kod XAML jest najpierw ładowany przez aplikację. Nie jest aktualizowana. Jest on podobny do znajdowania i zastępowania w języku XAML rzeczywistą wartością środowiska uruchomieniowego podczas uruchamiania aplikacji.
Zasoby motywu w strukturze słownika zasobów
Każdy zasób motywu jest częścią pliku XAML themeresources.xaml. W celach projektowych plik themeresources.xaml jest dostępny w folderze \(Program Files)\Windows Kits\10\DesignTime\CommonConfiguration\Neutral\UAP\SDK version<\>Generic folderu z instalacji zestawu Windows Software Development Kit (SDK). Słowniki zasobów w pliku themeresources.xaml są również odtwarzane w pliku generic.xaml w tym samym katalogu.
Środowisko uruchomieniowe systemu Windows nie używa tych plików fizycznych do wyszukiwania w czasie wykonywania. Dlatego są one specjalnie w folderze DesignTime i nie są domyślnie kopiowane do aplikacji. Zamiast tego te słowniki zasobów istnieją w pamięci w ramach samego środowiska uruchomieniowego systemu Windows, a odwołania zasobów XAML aplikacji do zasobów motywu (lub zasobów systemowych) rozpoznają je w czasie wykonywania.
Wskazówki dotyczące zasobów motywu niestandardowego
Postępuj zgodnie z tymi wytycznymi podczas definiowania i korzystania z własnych zasobów motywu niestandardowego:
Oprócz słownika "HighContrast" określ słowniki motywów zarówno dla "Jasny", jak i "Ciemny". Mimo że można utworzyć element ResourceDictionary z wartością "Default" jako klucz, preferowane jest jawne, a zamiast tego użyj polecenia "Light", "Dark" i "HighContrast".
Użyj rozszerzenia znaczników {ThemeResource} w: Style, Setters, Szablony kontrolek, Zestawy właściwości i Animacje.
Nie używaj rozszerzenia znaczników {ThemeResource} w definicjach zasobów w elementach ThemeDictionaries. Zamiast tego użyj rozszerzenia znaczników {StaticResource} .
WYJĄTEK: Możesz użyć rozszerzenia znaczników {ThemeResource} , aby odwołać się do zasobów, które są niezależne od motywu aplikacji w elementach ThemeDictionaries. Przykłady tych zasobów to zasoby kolorów wyróżniających, takie jak
SystemAccentColor, lub zasoby kolorów systemu, które są zwykle poprzedzone ciągiem "SystemColor", na przykładSystemColorButtonFaceColor.
Ostrzeżenie
Jeśli nie przestrzegasz tych wytycznych, może zostać wyświetlone nieoczekiwane zachowanie związane z motywami w aplikacji. Aby uzyskać więcej informacji, zobacz sekcję Rozwiązywanie problemów z zasobami motywu .
Rampa kolorów XAML i pędzle zależne od motywu
Połączony zestaw kolorów dla motywów "Jasny", "Ciemny" i "HighContrast" tworzą rampę kolorów systemu Windows w języku XAML. Niezależnie od tego, czy chcesz zmodyfikować motywy systemowe, czy zastosować motyw do własnych elementów XAML, ważne jest, aby zrozumieć, jak są ustrukturyzowane zasoby kolorów.
Aby uzyskać dodatkowe informacje na temat stosowania koloru w aplikacji systemu Windows, zobacz Kolor w aplikacjach systemu Windows.
Kolory motywu jasnego i ciemnego
Struktura XAML udostępnia zestaw nazwanych zasobów color z wartościami dostosowanymi do motywów "Jasny" i "Ciemny". W przypadku interfejsu WinUI 2 zasoby motywu są zdefiniowane w pliku Xaml wspólnych zasobów motywu. Nazwy kolorów są bardzo opisowe ich zamierzonego użycia i istnieje odpowiedni zasób SolidColorBrush dla każdego zasobu Color.
Wskazówka
Aby zapoznać się z wizualnym omówieniem tych kolorów, zobacz aplikację Galeria WinUI 3: Kolory
Aplikacja Galeria WinUI 3 zawiera interaktywne przykłady większości kontrolek, funkcji i funkcji interfejsu WinUI 3. Pobierz aplikację ze Sklepu Microsoft lub pobierz kod źródłowy w witrynie GitHub
Kolory motywu kontrastu systemu Windows
Oprócz zestawu zasobów udostępnianych przez strukturę XAML istnieje zestaw wartości kolorów pochodzących z palety systemu Windows. Te kolory nie są specyficzne dla środowiska uruchomieniowego systemu Windows lub aplikacji systemu Windows. Jednak wiele zasobów pędzla XAML używa tych kolorów, gdy system działa (a aplikacja jest uruchomiona) przy użyciu motywu "HighContrast". Platforma XAML udostępnia te kolory dla całego systemu jako zasoby kluczy. Klucze są zgodne z formatem nazewnictwa: SystemColor[name]Color.
Aby uzyskać więcej informacji na temat obsługi motywów kontrastu, zobacz Motywy kontrastu.
Kolor akcentu systemu
Oprócz kolorów motywu kontrastu systemu, kolor akcentu systemu jest dostarczany jako specjalny zasób koloru przy użyciu klucza SystemAccentColor. W czasie wykonywania ten zasób pobiera kolor określony przez użytkownika jako kolor wyróżniający w ustawieniach personalizacji systemu Windows.
Uwaga / Notatka
Chociaż można zastąpić zasoby kolorów systemu, najlepszym rozwiązaniem jest przestrzeganie opcji kolorów użytkownika, szczególnie w przypadku ustawień motywu kontrastu.
Pędzle zależne od motywu
Zasoby kolorów wyświetlane w poprzednich sekcjach służą do ustawiania właściwości Color zasobów SolidColorBrush w słownikach zasobów motywu systemu. Zasoby pędzla służą do stosowania koloru do elementów XAML.
Przyjrzyjmy się, jak wartość koloru dla tego pędzla jest określana w czasie wykonywania. W słownikach zasobów "Jasny" i "Ciemny" ten pędzl jest zdefiniowany w następujący sposób:
<SolidColorBrush x:Key="TextFillColorPrimaryBrush" Color="{StaticResource TextFillColorPrimary}"/>
W słowniku zasobów "HighContrast" ten pędzl jest zdefiniowany w następujący sposób:
<SolidColorBrush x:Key="TextFillColorPrimaryBrush" Color="{ThemeResource SystemColorWindowTextColor}"/>
Po zastosowaniu tego pędzla do elementu XAML jego kolor jest określany w czasie wykonywania przez bieżący motyw, jak pokazano w tej tabeli.
| Theme | Zasób koloru | Wartość środowiska uruchomieniowego |
|---|---|---|
| Light | TextFillColorPrimary | #E4000000 |
| Ciemny | TextFillColorPrimary | #FFFFFFFF |
| HighContrast | SystemColorWindowTextColor | Kolor określony w ustawieniach tekstu. |
Rampa typu XAML
Plik themeresources.xaml definiuje kilka zasobów, które definiują styl , który można zastosować do kontenerów tekstowych w interfejsie użytkownika, w szczególności dla textBlock lub RichTextBlock. Nie są to domyślne style niejawne. Są one udostępniane, aby ułatwić tworzenie definicji interfejsu użytkownika XAML, które są zgodne z rampą typu systemu Windows udokumentowaną w wytycznych dotyczących czcionek.
Te style są przeznaczone dla atrybutów tekstowych, które mają zostać zastosowane do całego kontenera tekstu. Jeśli chcesz, aby style były stosowane tylko do sekcji tekstu, ustaw atrybuty elementów tekstowych w kontenerze, takie jak w elem. Run in TextBlock.Inlines lub akapitu w obiekcie RichTextBlock.Blocks.
Style wyglądają następująco po zastosowaniu do elementu TextBlock:
| Styl | Weight | Rozmiar |
|---|---|---|
| Napisy | Regularny | 12 |
| Body | Regularny | 14 |
| Ciało silne | Półbold | 14 |
| Ciało duże | Regularny | 18 |
| Podtytuł | Półbold | 20 |
| Title | Półbold | 28 |
| Tytuł duży | Półbold | 40 |
| Display | Półbold | 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}"/>
Aby uzyskać wskazówki dotyczące korzystania z rampy typu systemu Windows w aplikacji, zobacz Typografia w aplikacjach systemu Windows.
Aby uzyskać szczegółowe informacje na temat stylów XAML, zobacz WinUI w witrynie GitHub:
Wskazówka
Aby zapoznać się z wizualnym omówieniem tych stylów, zobacz aplikację Galeria WinUI 3: Typography
BaseRichTextBlockStyle
TargetType: RichTextBlock
Dostarcza wspólne właściwości dla wszystkich innych stylów kontenera 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"/>
<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>
Uwaga: Style RichTextBlock nie mają wszystkich stylów rampy tekstu, które wykonuje TextBlock , głównie dlatego, że model obiektów dokumentu oparty na bloku dla biblioteki RichTextBlock ułatwia ustawianie atrybutów dla poszczególnych elementów tekstowych. Ponadto ustawienie właściwości TextBlock.Text przy użyciu właściwości zawartości XAML wprowadza sytuację, w której nie ma elementu tekstowego do stylu i dlatego trzeba będzie stylować kontener. Nie jest to problem w przypadku biblioteki RichTextBlock , ponieważ jej zawartość tekstowa zawsze musi znajdować się w określonych elementach tekstowych, takich jak Akapit, w którym można zastosować style XAML dla nagłówka strony, pod nagłówka strony i podobnych definicji rampy tekstu.
Różne style nazwane
Istnieje dodatkowy zestaw kluczowych definicji stylu , które można zastosować do stylu Przycisk inaczej niż domyślny styl niejawny.
NavigationBackButtonNormalStyle
TargetType: Przycisk
Ten styl zawiera kompletny szablon przycisku , który może być przyciskiem nawigacji wstecz dla aplikacji nawigacji. Domyślne wymiary to 40 x 40 pikseli. Aby dostosować styl, możesz jawnie ustawić właściwości Height, Width, FontSize i inne na przycisku lub utworzyć styl pochodny przy użyciu właściwości BasedOn.
Oto przycisk z zastosowanym zasobem NavigationBackButtonNormalStyle .
<Button Style="{StaticResource NavigationBackButtonNormalStyle}" />
Wygląda to tak:
NavigationBackButtonSmallStyle
TargetType: Przycisk
Ten styl zawiera kompletny szablon przycisku , który może być przyciskiem nawigacji wstecz dla aplikacji nawigacji. Jest on podobny do NavigationBackButtonNormalStyle, ale jego wymiary to 30 x 30 pikseli.
Oto przycisk z zastosowanym zasobem NavigationBackButtonSmallStyle .
<Button Style="{StaticResource NavigationBackButtonSmallStyle}" />
Rozwiązywanie problemów z zasobami motywu
Jeśli nie przestrzegasz wytycznych dotyczących korzystania z zasobów motywu, możesz zobaczyć nieoczekiwane zachowanie związane z motywami w aplikacji.
Na przykład po otwarciu wysuwanego z jasnymi motywami części aplikacji o ciemnych motywach również zmieniają się tak, jakby były w jasnym motywie. Lub jeśli przejdziesz do strony z jasnymi motywami, a następnie przejdziesz z powrotem, oryginalna strona o ciemnych motywach (lub jej części) wygląda teraz tak, jakby była w jasnym motywie.
Zazwyczaj te typy problemów występują, gdy udostępniasz motyw "Domyślny" i motyw "HighContrast", aby obsługiwać scenariusze o wysokim kontraście, a następnie używać motywów "Jasny" i "Ciemny" w różnych częściach aplikacji.
Rozważmy na przykład tę definicję słownika motywu:
<!-- 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>
Intuicyjnie wygląda to poprawnie. Chcesz zmienić kolor wskazywany myBrush przez w przypadku dużego kontrastu, ale w przypadku braku dużego kontrastu polegasz na rozszerzeniu znaczników {ThemeResource} , aby upewnić się, że myBrush wskazuje odpowiedni kolor motywu. Jeśli aplikacja nigdy nie ma elementu FrameworkElement.RequestedTheme ustawionego na elementach w drzewie wizualizacji, zwykle będzie to działać zgodnie z oczekiwaniami. Jednak napotkasz problemy w aplikacji, gdy tylko zaczniesz ponownie motywować różne części drzewa wizualnego.
Problem występuje, ponieważ pędzle są zasobami udostępnionymi, w przeciwieństwie do większości innych typów XAML. Jeśli masz 2 elementy w poddrzewach XAML z różnymi motywami odwołującymi się do tego samego zasobu pędzla, podczas gdy struktura przeprowadzi poszczególne pod drzewa podrzędne w celu zaktualizowania wyrażeń rozszerzeń znaczników {ThemeResource} , zmiany w udostępnionym zasobie pędzla zostaną odzwierciedlone w innym drzewie podrzędnym, co nie jest zamierzonym wynikiem.
Aby rozwiązać ten problem, zastąp słownik "Domyślny" oddzielnymi słownikami motywów dla motywów "Jasny" i "Ciemny" oprócz "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>
Jednak problemy nadal występują, jeśli którykolwiek z tych zasobów jest przywoływane we właściwościach dziedziczonych, takich jak Foreground. Niestandardowy szablon kontrolki może określać kolor pierwszego planu elementu przy użyciu rozszerzenia znaczników {ThemeResource}, ale gdy struktura propaguje dziedziczona wartość do elementów podrzędnych, zawiera bezpośrednie odwołanie do zasobu, który został rozwiązany przez wyrażenie rozszerzenia znaczników {ThemeResource}. Powoduje to problemy, gdy struktura przetwarza zmiany motywu podczas wprowadzania drzewa wizualnego kontrolki. Ponownie oblicza wyrażenie rozszerzenia znaczników {ThemeResource}, aby uzyskać nowy zasób pędzla, ale nie propaguje jeszcze tego odwołania do elementów podrzędnych kontrolki; dzieje się to później, na przykład podczas następnego przebiegu miary.
W związku z tym po przejściu przez drzewo wizualne kontrolki w odpowiedzi na zmianę motywu struktura przeprowadzi elementy podrzędne i zaktualizuje wszystkie wyrażenia rozszerzeń znaczników {ThemeResource} ustawione na nich lub obiekty ustawione na ich właściwości. W tym miejscu występuje problem; struktura przeprowadzi zasób pędzla i dlatego, że określa jego kolor przy użyciu rozszerzenia znaczników {ThemeResource}, jest on ponownie oceniany.
W tym momencie struktura wydaje się mieć zanieczyszczony słownik motywów, ponieważ ma teraz zasób z jednego słownika, który ma swój zestaw kolorów z innego słownika.
Aby rozwiązać ten problem, użyj rozszerzenia znaczników {StaticResource} zamiast rozszerzenia znaczników {ThemeResource}. Zgodnie z zastosowanymi wytycznymi słowniki motywów wyglądają następująco:
<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>
Zwróć uwagę, że rozszerzenie znaczników {ThemeResource} jest nadal używane w słowniku "HighContrast" zamiast rozszerzenia znaczników {StaticResource}. Ta sytuacja jest objęta wyjątkiem podanym wcześniej w wytycznych. Większość wartości pędzla używanych dla motywu "HighContrast" używa opcji kolorów, które są globalnie kontrolowane przez system, ale uwidocznione dla języka XAML jako specjalnie nazwanego zasobu (prefiks z "SystemColor" w nazwie). System umożliwia użytkownikowi ustawienie określonych kolorów, które powinny być używane dla ustawień motywu kontrastu za pośrednictwem Centrum ułatwień dostępu. Te opcje kolorów są stosowane do specjalnie nazwanych zasobów. Struktura XAML używa tego samego zdarzenia zmienionego motywu, aby zaktualizować te pędzle, gdy wykryje, że uległy zmianie na poziomie systemu. Dlatego w tym miejscu jest używane rozszerzenie znaczników {ThemeResource}.
Windows developer