Uno CalculatorがDark modeをサポートしたよ!っていうアップデートが配信されていたのでソースを読みながら同じようにしてもDarkにならんのやが…って1日考えてみた結果、Pre-releaseにしたら解決しました。という話です。
ThemeDictionariesが動かない
例えばこんな感じで書くと2019年12月2日現在のリリース版のUno Platformだと動きません。
<Application x:Class="UnoApp2.App" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"> <Application.Resources> <ResourceDictionary> <ResourceDictionary.ThemeDictionaries> <ResourceDictionary x:Key="Default"> <SolidColorBrush x:Key="ThemeBrush" Color="DarkBlue" /> <SolidColorBrush x:Key="BackgroundBrush" Color="Gray" /> </ResourceDictionary> <ResourceDictionary x:Key="Light"> <SolidColorBrush x:Key="ThemeBrush" Color="Red" /> <SolidColorBrush x:Key="BackgroundBrush" Color="#ccccff" /> </ResourceDictionary> </ResourceDictionary.ThemeDictionaries> </ResourceDictionary> </Application.Resources> </Application>
これは、前にも話題にしたインラインなResourceDictionaryの動作に制限があるためで、ThemeDictionaries内のResourceDictionaryは解釈されません。
ただ、あくまでもインラインなResourceDictionaryが問題なのであって以前に話題に挙げたようにglobal-level*1な ResourceDictionaryに定義すれば2019年12月2日現時点のリリース版でもThemeDictionariesの中身は解釈されます。 ただ、この場合常にテーマはLightとして処理されます。
ThemeDictionariesは動く
ThemeDictionariesは動きます。ただUno.UIのPre-Release版が必要です。
しつこいようですが2019年12月2日現在のリリース版は2019年7月23日にリリースされた1.45.0というバージョンが最新です。 このバージョンではThemeDictionariesを解釈することはできるのですが、DarkやHighContractを使用することはできません。
Light以外のテーマを使えるようになるには、2019年10月9日にマージされた#1628というプルリクエストを含んだバージョンにする必要があります。 これが一体どのバージョンからなのか…というのは探すのが大変なのであきらめました…
対応してるバージョンの境目を探すのも大変なので、とりあえず今回はUno.UIを2.1.0-dev.52
というバージョンにNuGetから更新します。
このバージョンはプレリリース版としてマークされているので、NuGetの画面からプレリリースを含める
というところにチェックを付けると表示されます。
Uno.UI以外はプロジェクトが生成されたときのデフォルトのままのバージョンを使ってビルドしても正しく動いているようです。
Uno.UIがプレリリース版に更新できたので、次のXAMLを適当な場所に保存します。ここではThemes/Styles.xaml
という名前で保存しました。
<ResourceDictionary xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"> <ResourceDictionary.ThemeDictionaries> <ResourceDictionary x:Key="Default"> <SolidColorBrush x:Key="ForegroundBrush" Color="DarkBlue" /> <SolidColorBrush x:Key="BackgroundBrush" Color="Gray" /> </ResourceDictionary> <ResourceDictionary x:Key="Light"> <SolidColorBrush x:Key="ForegroundBrush" Color="Red" /> <SolidColorBrush x:Key="BackgroundBrush" Color="#ccccff" /> </ResourceDictionary> </ResourceDictionary.ThemeDictionaries> </ResourceDictionary>
これを使用するMainPage.xamlを次の内容で作成しました。
<Page x:Class="UnoApp2.MainPage" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:d="http://schemas.microsoft.com/expression/blend/2008" xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" mc:Ignorable="d"> <Grid Background="{ThemeResource BackgroundBrush}"> <TextBlock Foreground="{ThemeResource ForegroundBrush}" Text="Hello, world !" Margin="20" FontSize="30" /> </Grid> </Page>
App.xamlにはUWPとUnoの互換性の都合でMergedDictionariesの設定を書いてあります。
<Application x:Class="UnoApp2.App" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"> <Application.Resources> <ResourceDictionary> <ResourceDictionary.MergedDictionaries> <ResourceDictionary Source="Themes/Styles.xaml" /> </ResourceDictionary.MergedDictionaries> </ResourceDictionary> </Application.Resources> </Application>
ここまでをビルドして実行すると次の結果になります。期待した通りの結果ですね。
ただ、Unoのテーマ実装ではまだ動的なテーマ変更に対応していません。おそらく#1766がマージされた日にはいろいろと解決するのでしょう…