Sledování změn systémových barev v UWP aplikacích

WinUI

7 years ago

Uživatelé milují personalizaci a očekávají, že se aplikace adaptují jejich volbám. Za tímto účelem můžeme ve svých aplikacích používat barvu motivu (accent color). Ale co když uživatel změní nastavení barev za běhu aplikace?

ThemeResource

XAML obsahuje ThemeResource markup extension . To nám umožňuje se dynamicky odkazovat na zdroje dle aktuálně vybraného systémového motivu. Kdykoliv uživatel změní barvu motivu nebo přepne mezi tmavým a světlým tématem, zdroj je aktualizován. Pro přístup k aktuální barvě motivu, můžete použít klíč SystemAccentColor .

<Grid>
   <Grid.Background>
      <SolidColorBrush Color="{ThemeResource SystemAccentColor}" />
   </Grid.Background>
</Grid>

Pro pohodlí je také možné přímo odkazovat na SolidColorBrush s barvou motivu pomocí ne-přímo intuitivního klíče SystemControlHighlightAccentBrush .

<Grid Background="{ThemeResource SystemControlHighlightAccentBrush}" />

Sledování změn

Přestože ThemeResource je ve většině případů dostačující, někdy potřebujeme být notifikování o změnách barev i mimo XAML. V takových situacích se vyplatí použít třídu UISettings. V kontrastu s podobnými Windows Runtime API nenabízí UISettings ani singleton vlastnost Current ani factory metodu GetForCurrentView , ale má pouze jednoduchý konstruktor. Kromě mnoha vlastností které nám dávají přístup k různým informacím o uživatelském rozhraní (CaretBlinkRate , CursorSize nebo dokonce HandPreference ) má třída i dvě užitečné události: TextScaleFactorChanged a ColorValuesChanged . Zatímco první z nich zpracovává změny ve škálování textu, druhá je volána kdykoliv se změní barevná nastavení systému.

UISettings uiSettings = new UISettings();
uiSettings.ColorValuesChanged += ColorValuesChanged;

Při zpracování události můžeme barvu motivu získat buď přímo přes slovník Resources nebo pomocí metody GetColorValue:

Color accentColor = sender.GetColorValue(UIColorType.Accent);
//nebo
Color accentColor = (Color)Resources["SystemAccentColor"];

Přístup k nastavení světlého/tmavého motivu není tak přímý. Musíme se podívat na barvu pozadí - UIColorType.Background - a zkontrolovat zda je černá nebo bílá:

var backgroundColor = sender.GetColorValue(UIColorType.Background);
var isDarkMode = backgroundColor == Colors.Black;

Varování: událost není vždy spolehlivá. Často je zavolána několikrát pro každou změnu barvy, ale někdy není zavolána vůbec. Zřejmě jde o bug.

Ukázkový kód

Připravil jsem testovací projekt, který demonstruje použití události UISettings.ColorValuesChanged s barvou motivu a se světlým a tmavým vzhledem systému. Řešení je dostupné na mém GitHubu.