SourceChord

C#とXAML好きなプログラマの備忘録。最近はWPF系の話題が中心です。

FluentWPF 0.3.0をリリースしました

0.2系のリリースからはだいぶ時間がかかりましたが、色々とまとまった機能追加ができたので、FluentWPF0.3.0としてリリースしました。

今回の変更内容は以下のようなものです。

  • osのテーマ・アクセントカラー設定への対応
  • ResourceDictionaryExクラス
    • OSのLight/Darkテーマ設定に応じてリソース切替を行う仕組みの導入

f:id:minami_SC:20180403010336g:plain

変更内容

アクセントカラーへの追従

OSのアクセントカラーの設定に追従できるようにしました。

今までのバージョンでも、AccentColorsクラスでOSのアクセントカラーを参照できました。
このクラスを少し改善して、OSの設定変更に追従するようにしました。
x:Staticでアクセスした場合はテーマ変更に追従できないので注意

            <StackPanel Orientation="Horizontal" Margin="5">
                <Border Background="{Binding Path=(fw:AccentColors.ImmersiveSystemAccentBrush)}">
                    <TextBlock Text="ImmersiveSystemAccentBrush" />
                </Border>
                <Border Background="White">
                    <StackPanel>
                        <RadioButton Content="Light"
                                     IsEnabled="False"
                                     IsChecked="{Binding Path=(fw:SystemTheme.Theme),
                                     Converter={StaticResource radioButtonConverter}, ConverterParameter=Light, Mode=OneWay}"/>
                        <RadioButton Content="Dark"
                                     IsEnabled="False"
                                     IsChecked="{Binding Path=(fw:SystemTheme.Theme),
                                     Converter={StaticResource radioButtonConverter}, ConverterParameter=Dark, Mode=OneWay}"/>
                    </StackPanel>
                </Border>
            </StackPanel>
            <StackPanel Orientation="Horizontal" Margin="5">
                <Border Background="{Binding Path=(fw:AccentColors.ImmersiveSystemAccentLight1Brush)}">
                    <TextBlock Text="ImmersiveSystemAccentLight1Brush"/>
                </Border>
                <Border Background="{Binding Path=(fw:AccentColors.ImmersiveSystemAccentLight2Brush)}">
                    <TextBlock Text="ImmersiveSystemAccentLight2Brush"/>
                </Border>
                <Border Background="{Binding Path=(fw:AccentColors.ImmersiveSystemAccentLight3Brush)}">
                    <TextBlock Text="ImmersiveSystemAccentLight3Brush" />
                </Border>
            </StackPanel>
            <StackPanel Orientation="Horizontal" Margin="5">
                <Border Background="{Binding Path=(fw:AccentColors.ImmersiveSystemAccentDark1Brush)}">
                    <TextBlock Text="ImmersiveSystemAccentDark1Brush" Foreground="White"/>
                </Border>
                <Border Background="{Binding Path=(fw:AccentColors.ImmersiveSystemAccentDark2Brush)}">
                    <TextBlock Text="ImmersiveSystemAccentDark2Brush" Foreground="White"/>
                </Border>
                <Border Background="{Binding Path=(fw:AccentColors.ImmersiveSystemAccentDark3Brush)}">
                    <TextBlock Text="ImmersiveSystemAccentDark3Brush" Foreground="White"/>
                </Border>
            </StackPanel>

            <StackPanel Orientation="Horizontal" Margin="5">
                <Border Background="{x:Static fw:AccentColors.ImmersiveSystemAccentBrush}">
                    <TextBlock Text="x:Static"/>
                </Border>
                <Border Background="{Binding Path=(fw:AccentColors.ImmersiveSystemAccentBrush)}">
                    <TextBlock Text="Binding" />
                </Border>
            </StackPanel>

f:id:minami_SC:20180221233148g:plain

ResourceDictionaryEXクラス

今回の更新の一番の目玉はコレ。
OSのLight/Darkのテーマごとに別々のResource定義を切り替える機能を追加しました。

アクリルなウィンドウ表示をするAcrylicWindowクラスなどでは、標準でこの機能を使ったスタイルに修正しています。
こんな風にOSのテーマ設定に応じて一部コントロールやウィンドウのデフォルト色設定が自動で切り替わります。

f:id:minami_SC:20180403010222g:plain

<fw:AcrylicWindow x:Class="FluentWpfTest.MainWindow"
        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"
        xmlns:local="clr-namespace:FluentWpfTest"
        xmlns:fw="clr-namespace:SourceChord.FluentWPF;assembly=FluentWPF"
        mc:Ignorable="d"
        Title="MainWindow" Height="300" Width="400">
    <Grid>
        <TextBlock Text="Hello World!!"
                   FontSize="32"
                   HorizontalAlignment="Center" VerticalAlignment="Center"/>
    </Grid>
</fw:AcrylicWindow>

アプリのテーマ設定~ResourceDictionaryEx.GlobalThemeプロパティ~

このプロパティを設定することで、アプリのテーマ設定を切り替える事ができます。

設定値 内容
Default この値を設定すると、OSのLight/Darkテーマ設定に応じて、アプリのテーマが自動で切り替わります(デフォルト値)
Light アプリ内では常にLightテーマを使用します
Dark アプリ内では常にDarkテーマを使用します

こんな風に、Appクラスのコンストラクタとかで設定すればOKです。
App.xaml.cs

    public partial class App : Application
    {
        public App()
        {
            SourceChord.FluentWPF.ResourceDictionaryEx.GlobalTheme = SourceChord.FluentWPF.ElementTheme.Default;
        }
    }

テーマごとのリソース定義~ResourceDictionaryEx.ThemeDictionariesプロパティ~

こんな風にThemeDictionariesプロパティ内に、OSのテーマ設定ごとのThemeDictionaryを定義することで、テーマごとに自動で切り替わるリソースを簡単に定義できます。

f:id:minami_SC:20180403010251g:plain

<fw:AcrylicWindow x:Class="FluentWpfTest.MainWindow"
        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"
        xmlns:local="clr-namespace:FluentWpfTest"
        xmlns:fw="clr-namespace:SourceChord.FluentWPF;assembly=FluentWPF"
        mc:Ignorable="d"
        Title="MainWindow" Height="300" Width="400">
    <fw:AcrylicWindow.Resources>
        <fw:ResourceDictionaryEx>
            <SolidColorBrush x:Key="bgBrush">White</SolidColorBrush>
            <fw:ResourceDictionaryEx.ThemeDictionaries>
                <fw:ThemeDictionary ThemeName="Light">
                    <Style TargetType="{x:Type Button}">
                        <Setter Property="Background" Value="LightBlue" />
                    </Style>
                </fw:ThemeDictionary>
                <fw:ThemeDictionary ThemeName="Dark">
                    <Style TargetType="{x:Type Button}">
                        <Setter Property="Background" Value="LightPink" />
                    </Style>
                </fw:ThemeDictionary>
            </fw:ResourceDictionaryEx.ThemeDictionaries>
        </fw:ResourceDictionaryEx>
    </fw:AcrylicWindow.Resources>
    <Grid>
        <Button Content="Button"
                HorizontalAlignment="Center" 
                VerticalAlignment="Center"
                Width="75"/>
    </Grid>
</fw:AcrylicWindow>

ThemeDictionaryクラスは、ResourceDictionary派生のクラスとなってます。Themeプロパティで対象のテーマ名を指定する以外は、普通のResourceDictionaryと同じように使えます。

今後の予定

これから、以下のような更新をしていこうと考えてます。

Light/Dark用テーマの拡充

今回のバージョンアップで、ResourceDictionaryExクラスを使って、テーマごとのリソース切替ができるようになりました。
ですが、こういう仕組みは作りましたが、実際に切り替えるテーマ自体はまだあまり作り込めていません。

ということで、これから少しずつ各テーマごとのデザインを、もう少し作り込んでいきたいと思っています。

RS4のFluent Design Systemへの追従

今月初頭には、RS4ことWindows10 Spring Creators Updateが配信される、なんて話題がちらほら聞こえてきています。

RS4では、Fluent Designの各種エフェクトも色々とリファインされてきているので、RS4のエフェクトを見ながら再現度を高めていこうと思います。

Wikiの拡充

だいぶ機能が増えてきたので、使い方をREADMEに全部書くのもつらくなってきました。
ということで、Wikiにドキュメントを書いていこうと思ってます。
が、なかなか筆不精で進まない・・・orz

こちらも気の向いたときに書き進めていこうと思います。

今日のところはこの辺まで。