WinUI3ではStyle.Triggersがないので代替手段でマウスオーバー時の背景色変更する

もくじ
https://tera1707.com/entry/2022/02/06/144447#WinUI3

やりたいこと

以前調べた、WPFStyle.Triggerを使ってマウスオーバー時に背景色を変える方法をWinUI3でもやろうとすると、Style.Triggerがなくなって使えなくなっていた。

WinUI3っで、お手軽に掲題のようなことをしたい場合、どうしたらいいのか、調べたい。

前提

  • VisualStudio2022 Community 17.1.4
  • WinUI3.0
  • Windows App SDK 1.0
  • 2022年5月の時点で調査実施

結論

WPFでやっていた、Style.Triggerを使って簡単にマウスオーバー時に背景色を変えるような方法は、WinUI3では見つけられなかった。

代わりに、
例えばボタンの背景色をマウスオーバー時に変えたいのであれば、
generic.xamlから標準のボタンのstyle(とその中のテンプレート)をコピーして、必要なところ(今回であれば、<VisualState x:Name="PointerOver">の色をいじってるあたり)をカスタムするのが、WinUI3では近道だと現時点では思う。

具体的なやり方は、
以前調べたWinUI3でのテーマカラー対応の中でやっている「独自の色ボタンのための作業をする」と「generic.xamlから、標準のボタンのstyleをコピーして、自分のリソースディクショナリにコピーする」を参照。

そのほか、xamlに数行書くだけでそれができるような方法は今のところ見つけられていない。 上の方法は、コピーする量が結構多い、かついじる部分は少なめになるので気持ちよくはないが、わかりやすいといえばわかりやすいやり方なので、個人的には嫌いじゃない。

しらべたことのメモ

以下は、なにかいいやり方がないか、いろいろ調べたときの徒然メモ。


いろいろ代替手段を探しているときにWindows.UI.Xamlの‘FrameworkElement.Triggers‘というのを見つけたのでそれを調べていたら、EventTrigger クラスのドキュメントに、下記のように書いてあった。

Triggers、EventTrigger、Actions、BeginStoryboardは一般的に使用されていません。これらのAPIは、主にMicrosoftSilverlightで元々使用されていたXAMLとの互換性のために存在します。

とのこと。WinUI3では、「Trigger」系はもはや使われてないっぽい。


さらなる代替手段として、VisualStateManager クラス というのが使えそうなにおいがする。→こちら

調べてみる。

調べてみた。
例えばこんな感じで書くと、ボタンをおしたときに色が変わるボタンが出来上がる。

<Page
    x:Class="PageTemplate.BlankPage1"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:local="using:PageTemplate"
    xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
    xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
    mc:Ignorable="d"
    Background="{ThemeResource ApplicationPageBackgroundThemeBrush}">
 
    <Button Width="100" Height="100" Background="White" Name="aaa">
        <Button.Template>
            <ControlTemplate TargetType="Button">
                <Grid >
                    <VisualStateManager.VisualStateGroups>
                        <VisualStateGroup x:Name="CommonStates">

                            <VisualStateGroup.Transitions>
                                <VisualTransition To="PointerOver" GeneratedDuration="0:0:3"/>
                            </VisualStateGroup.Transitions>

                            <VisualState x:Name="Normal" />

                            <VisualState x:Name="Pressed">
                                <Storyboard>
                                    <ColorAnimation Storyboard.TargetName="ButtonBrush" Storyboard.TargetProperty="Color" To="Red" />
                                </Storyboard>
                            </VisualState>
                        </VisualStateGroup>
                    </VisualStateManager.VisualStateGroups>
                    <Grid.Background>
                        <SolidColorBrush x:Name="ButtonBrush" Color="Green"/>
                    </Grid.Background>
                </Grid>
            </ControlTemplate>
        </Button.Template>
    </Button>
</Page>

が、上記のようにControlTemplateを自前でつくると、好きな見た目にはできるが、元のボタンからはかけ離れた見た目になり、 今回調べようとしていた「簡単に、マウスオーバー時の色を変える」から離れてしまう。

どうも、上記をやるのであれば、触っている限りの個人的感触では、
以前調べたWinUI3でのテーマカラー対応の中でやっている「generic.xamlから、標準のボタンのstyleをコピーして、自分のリソースディクショナリにコピーする」をやって、必要なところの色だけを変える、ということをやる方が、ぱっと見のコード量は、標準のstyle(テンプレート)をコピペする分増えてしまうが、やることは簡単&ベースの見た目も元のボタンに近づけることができると感じる。

また、マイクロソフトもそのやり方を推しているように感じる。

※ボタンの見た目をガラッと変えていい場合はなおさら、標準ボタンのstyleを取ってきて、その中のテンプレートを好きにいじってやればいい。

なので、

  • マウスオーバー時のボタンの色を変えたい
  • 標準とは異なる自前のかっこいいボタンをつくりたい

のどの場合も、(styleをちょちょっといじるお手軽さはもう無理とあきらめて)「generic.xamlから、標準のボタンのstyleをコピーして、必要なところをカスタムする」のが、WinUI3では近道だと思った。

参考

FrameworkElement.Triggersプロパティ(Microsoft.UI.Xaml

https://docs.microsoft.com/ja-jp/windows/winui/api/microsoft.ui.xaml.frameworkelement.triggers?view=winui-3.0

Loadedイベント
<EventTrigger>RoutedEventプロパティに何もセットしないと、Loadedがトリガーになるらしい。

https://docs.microsoft.com/en-us/uwp/api/windows.ui.xaml.frameworkelement.loaded?view=winrt-22000

ストーリーボードの概要
<EventTrigger>にセットするStoryboardの使い方。.net Framework4.xの説明ページっぽいが、ほぼ同じか。

https://docs.microsoft.com/ja-jp/dotnet/desktop/wpf/graphics-multimedia/storyboards-overview?view=netframeworkdesktop-4.8&viewFallbackFrom=netdesktop-6.0

VisualStateManager クラス

https://docs.microsoft.com/ja-jp/uwp/api/windows.ui.xaml.visualstatemanager?view=winrt-18362

参考書

WinUI3

WinUI3でアプリを作ろうと思ったときのとっかかりによかった。 msdocsに書いてある情報を、体系的に、順番に読みたいな、というときによいかも。(ただし英語)
この本で分からなかった、かゆいところに手が届かなかった部分を私は記事にしてる感じ。

C#①

表紙に書いてある通り、教科書として最適。 これからC#を勉強したいけど、ネットだけで勉強するのは効率が悪いから体系的に学べる本が欲しいときや、 ちょっとC#を勉強してコード書けるようになったけど、もう少し広く深く知りたいなというときによいと思う。
私は仕事で触れるコードを軸に、基本ネットで断片的にC#を学んだので、その知識の隙間を埋めて枝葉を広げるためにとても分かりやすかった。

C#②

C#の文法的に色々できるのは分かったが、いざ実装するときに、わかったことを使ってどう実装すればいいのか?と悩んだときに指針になりそうな本。
「プロパティ等の名前の付け方、どうすればいい?」「情報をクラス外部に見せるときに、プロパティにすべき?メソッドにすべき?」「異常だと判定したいとき、どんなときにどんな例外をスローすべき?」などなど、勉強になる部分が山ほどあった。
私のように「コードは書くけどこれであってるのか自信がない、レビューで指摘されるのが嫌だ、実装時の(心の)よりどころが欲しい」という人に最適。