WInUI3関連記事
https://tera1707.com/entry/2022/02/06/144447#WinUI3
やりたいこと
WinUI3 各コントロールの見た目の色をいじりたい。
例えば、ボタンのマウスオーバー時の色を自分の好きな色に変えたい。
そのやり方を調べたときに辿った道順をメモする。
色の出どころがどこなのか?調べる
まずは、ボタンのマウスオーバー時の色がどこから来てるのか?を調べる。
C:\Program Files (x86)\Windows Kits\10\DesignTime\CommonConfiguration\Neutral\UAP
に、Windowsのバージョンごとに、標準のResourceDictionaryがある。
おそらく、マウスオーバー時の色を変えたいくらいであれば、どのバージョンのResourceDictionraryを見ても同じなので、
一旦10.0.19041.0
を開く。
その中の\10.0.19041.0\Generic\generic.xaml
を開く。
★22/10/03追記
WinUI3の標準のResource、styleは上記ではなかった。
→こちらを参照
→ https://tera1707.com/entry/2022/10/02/235818
今回は、マウスオーバー時の色を変えたいだけなので、マウスオーバーの時の色変化は標準でどうやってるか?を見てみる。
→<VisualState x:Name="PointerOver">
あたりを見る。
そうすると、そこには下記のようなことが書いてある。
Background
をButtonBackgroundPointerOver
にするBorderBrush
をButtonBorderBrushPointerOver
にするForeground
をButtonForegroundPointerOver
にする
例えばその中の ButtonBackgroundPointerOver(マウスオーバー時のボタンの背景の色) が実際何色かを見ていくと、
<StaticResource x:Key="ButtonBackgroundPointerOver" ResourceKey="SystemControlBackgroundBaseLowBrush" />
とあり、<SolidColorBrush x:Key="SystemControlBackgroundBaseLowBrush" Color="{ThemeResource SystemColorButtonFaceColor}" />
とある。
<StaticResource x:Key="ButtonBackgroundPointerOver" ResourceKey="SystemControlBackgroundBaseLowBrush" />
はgeneric.xamlの中に3つあり、 それぞれ<ResourceDictionary x:Key="Default">
、<ResourceDictionary x:Key="HighContrast">
、<ResourceDictionary x:Key="Light">
の中にある。 そのそれぞれが、ライト、ダーク、ハイコントラスト時の色の定義っぽい。
このSystemColorButtonFaceColor
は、下記のシステムカラーの定義の中にあった。
C:\Program Files\Microsoft Visual Studio\2022\Community\DesignTools\SystemThemes\WinUI\SystemColors.xaml
私のVS2022がCommunityなので上記のフォルダだが、Professional版等、ほかのエディションだったらまた別のフォルダにあると思われる。
色は<Color x:Key="SystemColorButtonFaceColor">#FFF0F0F0</Color>
とあった。
ここが、色の出所っぽい。
実際に色を変えてみる
じゃあその#FFF0F0F0
を変えればいいのかなと思ったが、
SystemColorButtonFaceColor
のようなSystemColors.xaml
の中の色の定義は、自分のアプリのリソースではないので変えられなさそう。
SystemControlBackgroundBaseLowBrush
は、それを使っている個所が多数あるので、変えることができたとしても変えたくない。
ButtonBackgroundPointerOver
の色を上書きして、色を変えてみる。
まずは、簡易的に、メイン画面のリソースに、上書した色を書いてみる。
今回は、黄色にしてみた。
<Window x:Class="DefaultControlTemplateTest.MainWindow" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:local="using:DefaultControlTemplateTest" xmlns:d="http://schemas.microsoft.com/expression/blend/2008" xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" mc:Ignorable="d"> <StackPanel Orientation="Horizontal" HorizontalAlignment="Center" VerticalAlignment="Center"> <StackPanel.Resources> <SolidColorBrush x:Key="ButtonBackgroundPointerOver" Color="Yellow" /> </StackPanel.Resources> <Button x:Name="myButton" Click="myButton_Click">Click Me</Button> </StackPanel> </Window>
これで、マウスオーバー時、
のような感じになった。
その後
あとは、そのほかのイベント(Disable時やボタン押下時)のときにも同じように、標準の色変化と違う色変化をしたければ、<VisualState x:Name="Pressed">
や<VisualState x:Name="Disabled">
のときの色を上書してやればOK。
220411追記 SystemAccentColorLight1,2,3,SystemAccentColorDark1,2,3の正体
Fluent Xaml Theme Editorで作ったリソースディクショナリの中に、掲題のようなリソースがあったのだが、これがなんだかよくわかってなかった。
→下記に書いてあった。
Fluent Xaml Theme Editorの吐いたリソースディクショナリのコレ
を見て、勝手に「Lightとついてる奴は、ライトテーマを選んでいるときに、アクセントカラーとして使われる奴なんだろうな。(でも、<ResourceDictionary x:Key="Light">
のなかにも‘
これはそういう意味ではなく、
キー名 | 意味 |
---|---|
SystemAccentColorDark3 | SystemAccentColorよりとても暗い色 |
SystemAccentColorDark2 | SystemAccentColorより暗い色 |
SystemAccentColorDark1 | SystemAccentColorよりちょっと暗い色 |
SystemAccentColor | 元のアクセントカラーの値 |
SystemAccentColorLight1 | SystemAccentColorよりちょっと明るい色 |
SystemAccentColorLight2 | SystemAccentColorより明るい色 |
SystemAccentColorLight3 | SystemAccentColorとても明るい色 |
という意味らしい。だから、下記のようなxamlを書いて、
<StackPanel Orientation="Horizontal"> <Grid Width="50" Height="50" Background="{ThemeResource SystemAccentColorDark3}"/> <Grid Width="50" Height="50" Background="{ThemeResource SystemAccentColorDark2}"/> <Grid Width="50" Height="50" Background="{ThemeResource SystemAccentColorDark1}"/> <Grid Width="50" Height="50" Background="{ThemeResource SystemAccentColor}"/> <Grid Width="50" Height="50" Background="{ThemeResource SystemAccentColorLight1}"/> <Grid Width="50" Height="50" Background="{ThemeResource SystemAccentColorLight2}"/> <Grid Width="50" Height="50" Background="{ThemeResource SystemAccentColorLight3}"/> </StackPanel>
windowsのアクセントカラーの設定を青にしていると、
こうなる
緑にしてると
こうなる。
で、Fluent Xaml Theme Editorで作ったリソースディクショナリのように、自分のコードの中に‘
だから、アクセントカラーの色を使っているコントロールの色を、ユーザーのアクセントカラーの設定に左右されない色にしたいときは、これを上書き(オーバーライド)すればよいかも。
(もしくは、style等を使ってアクセントカラーを使うのをやめさせるか)
220411追記 {StaticResource 色のキー名} と {ThemeResource 色のキー名} の違い
StaticResource だと、起動時に一回だけリソースが読み込まれる。
ThemeResourceだと、テーマ変更時に再度読み込まれる。
ためしに、下記のようなxamlを書いてみる。
Dark1,2,3だけがStaticResource
を使っていて、SystemAccentColorとLight1,2,3がThemeResource
を使っている。
<StackPanel Orientation="Horizontal"> <Grid Width="50" Height="50" Background="{StaticResource SystemAccentColorDark3}"/> <Grid Width="50" Height="50" Background="{StaticResource SystemAccentColorDark2}"/> <Grid Width="50" Height="50" Background="{StaticResource SystemAccentColorDark1}"/> <Grid Width="50" Height="50" Background="{ThemeResource SystemAccentColor}"/> <Grid Width="50" Height="50" Background="{ThemeResource SystemAccentColorLight1}"/> <Grid Width="50" Height="50" Background="{ThemeResource SystemAccentColorLight2}"/> <Grid Width="50" Height="50" Background="{ThemeResource SystemAccentColorLight3}"/> </StackPanel>
これを、アクセントカラーで青色を選択した状態で、上記コードを起動すると下記のようになり、
そのままアプリ起動した状態でアクセントカラーを緑に変更すると、下図のようになる。 (Dark1,2,3の方が、OSのアクセントカラーの変更についてきていない)
220411追記 私と同じで、ブラシがたくさんありすぎて迷い込んだ方のissue
ブラシがたくさんありすぎてわけわからないので一覧が欲しい、とこの方も言っている様子。
まったく同じ気持ちだったのだが、ここで言われているのが、
- コントロールのテーマブラシとして名前の付いたブラシは1000を超える数がある。
- システムのブラシと色は約150〜200ある。
- ただし実際の色は、25種類前後だけ。
とのこと。
①が、C:\Program Files (x86)\Windows Kits\10\DesignTime\CommonConfiguration\Neutral\UAP<sdkVersion>\10.0.19041.0\Generic\themeresources.xaml
の2090行目より下にあるSliderContainerBackground
のような、コントロールの種類名がキーについたブラシのことっぽい。
②が、themeresources.xaml
の上の方にあるSystemなんとかかんとか
というColor
と、SystemControlなんとかかんとか
という名前のSolidColorBrush
っぽい。(10.0.22000.0のthemeresources.xamlの204~327行目あたり)
そのすぐ上あたりに、そのブラシで使っている色(Color
)が定義されてる。(SystemAccentColor
など、特別な奴は、③の中にある)
③が、‘C:\Program Files\Microsoft Visual Studio\2022\Community\DesignTools\SystemThemes\WinUI\SystemColors.xaml‘ にある色とブラシのことっぽい。
220411追記 で、結局winui3でテーマ対応(ダーク、ライト、ハイコントラスト)対応するにはどうしたらいいのか?
考え中...
一番上に書いたやり方で、①をオーバーライドしてやれば、コントロールごとの色を変えることは可能だった。
では、もっと広い範囲の色を一気に変えたいとき等に、②③はオーバーライドできるのか?ためす。
参考
テーマの色を変えたいときのガイドライン。 デフォルトのリソースディクショナリがどこにあるか?や、色(をはじめとしたリソース)の変え方が書かれてる
SystemColorの定義が書かれていそうな個所を探していたときに見つけた 「WPFでの」 その辺がありそうなフォルダについて書かれた公式doc。
この辺をいろいろ見ていたら「winui」というフォルダがあり、そこを見たら、上で書いたフォルダが見つかった。
(WinUI3でSystemColorsの定義が書かれてそうなファイルについての公式docは見つけられなかった)
WinUI3のコントロールの見本市アプリ。
参考書
WinUI3
WinUI3でアプリを作ろうと思ったときのとっかかりによかった。
msdocsに書いてある情報を、体系的に、順番に読みたいな、というときによいかも。(ただし英語)
この本で分からなかった、かゆいところに手が届かなかった部分を私は記事にしてる感じ。
C#①
表紙に書いてある通り、教科書として最適。
これからC#を勉強したいけど、ネットだけで勉強するのは効率が悪いから体系的に学べる本が欲しいときや、
ちょっとC#を勉強してコード書けるようになったけど、もう少し広く深く知りたいなというときによいと思う。
私は仕事で触れるコードを軸に、基本ネットで断片的にC#を学んだので、その知識の隙間を埋めて枝葉を広げるためにとても分かりやすかった。
C#②
C#の文法的に色々できるのは分かったが、いざ実装するときに、わかったことを使ってどう実装すればいいのか?と悩んだときに指針になりそうな本。
「プロパティ等の名前の付け方、どうすればいい?」「情報をクラス外部に見せるときに、プロパティにすべき?メソッドにすべき?」「異常だと判定したいとき、どんなときにどんな例外をスローすべき?」などなど、勉強になる部分が山ほどあった。
私のように「コードは書くけどこれであってるのか自信がない、レビューで指摘されるのが嫌だ、実装時の(心の)よりどころが欲しい」という人に最適。