WPFでFluentデザイン

2025年5月10日土曜日

C# WPF

記事のカテゴリー:C#、.NET 9、WPF

.NET 9からWPFでFluentデザインを扱えるようになりました。FluentデザインはWindows 10以降、Microsoft製品で採用されているデザインです。.NET 9の時点では導入したばかりなせいか、いくつかのコントロールの外観に問題があるようです。

WPFアプリにFluentデザインを適用する方法

ApplicationクラスのThemeModeプロパティを設定します。

XAML:

<Application
    x:Class="WpfApp1.App"
    ...
    ThemeMode="System" />

ThemeModeプロパティの型はThemeMode構造体になっています(列挙型じゃない)。詳しくはMicrosoft Learnを参照してください。

また、WindowクラスもThemeModeプロパティを持っていてウィンドウ単位で設定することもできます。

Fluentデザインを切り替える方法

ThemeModeプロパティにはThemeMode構造体を見ればわかる通りNoneSystemLightDarkの4つの値があり、NoneはFluentデザイン以前の従来のデザインを表しています。アプリ起動中、FluentデザインとNoneの間で切り替えることはできませんが、SystemLightDarkの3つの間では切り替えることができます。

C#:

Application.Current.ThemeMode = ThemeMode.Dark;

ただし、コードでのThemeModeプロパティの変更は試験機能のため、プロジェクトファイルを編集するかPragmaディレクティブを利用してエラーを抑制する必要があります。

XML:

<Project Sdk="Microsoft.NET.Sdk">

  <PropertyGroup>
    ...
	<NoWarn>$(NoWarn);WPF0001</NoWarn>
  </PropertyGroup>
  
  ...
</Project>

ListViewの外観

ListViewGridViewに対応したスタイルが定義されておらず、正しく表示されません。

回避方法

参照の項にある「ListView のスタイルとテンプレート」から定数、ListViewItemListViewのスタイルをコピーします。

XAML:

<!--  定数をコピーする  -->
<!--Control colors.-->
<Color x:Key="WindowColor">#FFE8EDF9</Color>
<Color x:Key="ContentAreaColorLight">#FFC5CBF9</Color>
<Color x:Key="ContentAreaColorDark">#FF7381F9</Color>
...

<!--  ListViewItem のスタイルをコピーする  -->
<!--  標準のスタイルを上書きせずに独自のキーを設定する (例えば、"GridViewItemStyle")  -->
<Style x:Key="GridViewItemStyle" TargetType="ListViewItem">
    ...
</Style>

<!--  ListView のスタイルをコピーする  -->
<!--  標準のスタイルを上書きせずに独自のキーを設定する (例えば、"GridViewStyle")  -->
<!--  ItemContainerStyle に上記の ListViewItem のスタイルを指定する  -->
<Style x:Key="GridViewStyle" TargetType="ListView">
    <Setter Property="ItemContainerStyle" Value="{StaticResource GridViewItemStyle}" />
    ...
</Style>

XAML:

<ListView Style="{StaticResource GridViewStyle}">
    <ListView.View>
        <GridView />
    </ListView.View>
</ListView>

DataGridの外観

DataGridはダークモード、非活性(IsEnabledプロパティがfalse)の状態で真っ白になります。これはスタイルの非活性時に適用されるVisualStateで背景色にControlLightColor(値は白)をおそらく間違って指定しているためです。

回避方法

参照の項にある「Fluent.Light.xaml」(あるいは「Fluent.Dark.xaml」)からDataGridのスタイルをコピーします。該当するVisualStateStoryboardを削除します。

XAML:

<VisualStateManager.VisualStateGroups>
    <VisualStateGroup x:Name="CommonStates">
        <VisualState x:Name="Disabled">
            <!--<Storyboard>
                <ColorAnimationUsingKeyFrames Storyboard.TargetName="border" Storyboard.TargetProperty="(Panel.Background).                       (SolidColorBrush.Color)">
                    <EasingColorKeyFrame KeyTime="0" Value="{DynamicResource ControlLightColor}" />
                </ColorAnimationUsingKeyFrames>
            </Storyboard>-->
        </VisualState>
        <VisualState x:Name="Normal" />
    </VisualStateGroup>
</VisualStateManager.VisualStateGroups>

参照