sh1’s diary

プログラミング、読んだ本、資格試験、ゲームとか私を記録するところ

WPF UI(UI ライブラリ)の使い方(1)

WPFGUI ライブラリ「WPF UI」を使ってみる機会があったので、基本的な使い方をメモ。

WPFGUI ライブラリは、以下のようなものが色々あります。(2023/08/09 時点)

もちろん他にも GUI のライブラリは、種類があると思います。GitHubwpf タグで上位に出てくるライブラリがこのあたりでした。

個人的によいなと思ったライブラリを先に挙げると、「Material Design」や「WPF UI」は、現在も更新がありアクティブなリポジトリだと思いました。

逆に、「ModernWpf」は、デザインが魅力的な一方で、更新が 2022 年で途絶えるなどメンテナンスがあやしいです。おしい。「MashApps.Metro」も Release は 2023 年にありますが、珍しくバグフィクスが入った感じで、実際のところその前のリリースは 2021 年です。実際のところ、UI はよくできているのですが、古い印象のデザインもあります。(成熟したライブラリなのだと思いますが)

大体のライブラリは、リリースのページからデモアプリをダウンロードできるのでコードをダウンロードする前にコントロールを確認できるデモアプリをダウンロードしてみてください。

特に、「WPF UI」は、web 上のドキュメントが不足ぎみです。一方で、デモのサンプル上ではコード付きになっているので、どのライブラリのサンプルよりも完成度の高いデモアプリだと思います。(もちろん、リポジトリからコードを取得して、該当する xaml を調べればいいのですが、WPF UI に関してはリリースのデモアプリのコードを読んだほうがわかりやすいと思います)

思っているよりもライブラリの UI テーマの雰囲気がより掴めると思います。(また、デモアプリを操作すると思ったよりも変な挙動、バグっぽい挙動をすることもあります。残念だけど、そういうときは避けた方が無難)

インストールと初期設定

2023 年 8 月時点、バージョン「3」はプレビュー状態なので安定した「2.0.3」を利用しています。

App.xaml にライブラリを追加します。公式のサンプルでは Dark テーマになっていたので Light にします。

<Application x:Class="Sample.App"
             xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
             xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
             xmlns:local="clr-namespace:Sample"
             xmlns:ui="http://schemas.lepo.co/wpfui/2022/xaml"
             StartupUri="MainWindow.xaml">
    <Application.Resources>
        <ResourceDictionary>
            <ResourceDictionary.MergedDictionaries>
                <ui:ThemesDictionary Theme="Light" />
                <ui:ControlsDictionary />
            </ResourceDictionary.MergedDictionaries>
        </ResourceDictionary>
    </Application.Resources>
</Application>

とりあえず、この時点でビルドしてみて、正しくビルドが通ることをチェックしておきます。

補足(直接指定)

別の書き方として、リソースを直接指定することもできるみたいです。

Application>
  <Application.Resources>
    <ResourceDictionary>
      <ResourceDictionary.MergedDictionaries>
        <ResourceDictionary Source="pack://application:,,,/Wpf.Ui;component/Styles/Theme/Dark.xaml" />
        <ResourceDictionary Source="pack://application:,,,/Wpf.Ui;component/Styles/Wpf.Ui.xaml" />
      </ResourceDictionary.MergedDictionaries>
    </ResourceDictionary>
  </Application.Resources>
</Application>

テーマの操作はコード中から指定するなど、色々あるみたいなので、公式を「参照」のこと。

補足(テーマの指定)

OS が背景色やアクセントカラーを変更したときに、テーマを自動的に追従させる例。

public partial class MainWindow : Window
{
    public MainWindow()
    {
        InitializeComponent();

        Loaded += (sender, args) =>
        {
            Wpf.Ui.Appearance.Watcher.Watch(
                this,                                  // Window class
                Wpf.Ui.Appearance.BackgroundType.Mica, // Background type
                true                                   // Whether to change accents automatically
            );
        };
    }
}

XAML からライブラリを利用するための設定

名前空間ui を追加しています。慣例なのか、他のライブラリでも名前空間 ui をよく利用しています。(名前を変えれば複数利用もできそうだけど、なにか衝突しそうな怖さがあった)

xmlns:ui="http://schemas.lepo.co/wpfui/2022/xaml"

MainWindow のコードに追加した例は、以下。(公式のサンプルでも紹介されています)

ちいさなアイコンですが SymbolIcon を表示できていれば OK です。このアイコンセットは microsoft の「Microsoft Fluent Design System Icon」にあわせてデザインされているみたいで、1500種類以上の準備があります。

ベクター形式、および、16x16~512x512までのサイズが用意されているようなので、基本的なアイコンをこれでサポートできるのは楽。(アイコンを指定する名称(文字コード)は、デモアプリを利用するのが便利だと思います)

<Window x:Class="Sample.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:ui="http://schemas.lepo.co/wpfui/2022/xaml"
        xmlns:local="clr-namespace:Sample"
        mc:Ignorable="d"
        Title="MainWindow" Height="450" Width="800">
    <Window.Resources>
    </Window.Resources>
    <Grid>
        <ui:SymbolIcon Symbol="Fluent24"/>
    </Grid>
</Window>

公式のデモよりアイコンサンプル

システムのテーマを適用する

この内容は、公式のコンテンツに掲載がありません。内容に間違いがあるかもしれません。

後述する Snackbar は、システムのテーマを適用しないとデモアプリの色と違うカラーで表示されてしまいます。(上記のテーマだけでは、システムの色は設定されないところがある?)

デフォルトの状態:

システムのテーマを適用した状態:

変更箇所はどこでもいいので、アクセントに SystemAccent を適用すること。

public partial class App : Application
{
    protected override void OnStartup(StartupEventArgs e)
    {
        base.OnStartup(e);

        Wpf.Ui.Appearance.Accent.ApplySystemAccent();
    }
}

公式の Wpf.Ui.SimpleDemo では、MainWindow のコンストラクタ内で実行されています。

メニュー

この内容は、公式のコンテンツに掲載がありません。内容に間違いがあるかもしれません。

WPF で用意されているメニューは、デザインを拡張することが難しいというか面倒なので、ちょっと綺麗にしたいならこれでいい感じもします。

<Window x:Class="Sample.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:ui="http://schemas.lepo.co/wpfui/2022/xaml"
        xmlns:local="clr-namespace:Sample"
        mc:Ignorable="d"
        Title="MainWindow" Height="450" Width="800">
    <Window.Resources>
    </Window.Resources>
    <Grid>
        <Grid.RowDefinitions>
            <RowDefinition Height="Auto" />
            <RowDefinition Height="*" />
        </Grid.RowDefinitions>
        <Menu Grid.Row="0" Background="#EEEEEE">
            <ui:MenuItem Header="With icon" SymbolIcon="StoreMicrosoft24">
                <MenuItem Header="Check" IsCheckable="True"/>
            </ui:MenuItem>
        </Menu>
        <ui:SymbolIcon Grid.Row="1" Symbol="Fluent24"/>
    </Grid>
</Window>

面白いところは、デフォルトの MenuItem と WPF UI が提供している MenuItem を混ぜて使うことができます。

<Menu Grid.Row="0" Background="#EEEEEE">
    <ui:MenuItem Header="With icon" SymbolIcon="StoreMicrosoft24">
        <MenuItem Header="Check" IsCheckable="True"/>
        <Separator />
        <ui:MenuItem Header="With icon" SymbolIcon="StoreMicrosoft24" />
    </ui:MenuItem>
</Menu>

基本的には、普通に WPF の提供する MenuItem を継承して ui:MenuItem としているだけみたいです。とんでもないオリジナルコントロール化しているわけでは、ないです。

参考