.NET Core 正式対応版 MahApps.Metro Ver. 2【exhibition #1 WPF UI Gallery】
WPF UI Gallery で紹介中の MahApps.Metro から .NET Core 対応版となる Ver.2.0.0 が正式リリースされました。
そこで .NET Core 対応版が既にリリース済みの Material Design In XAML Toolkit と MahApps.Metro を統合して使用する場合のインストール手順と設定を紹介します。
この連載は Visual Studio 2019 Community Edition で .NET 5.0 以上 と C# + Prism 8.0 以降 + MahApps.Metro + Material Design In XAML Toolkit を使用して 、WPF アプリケーションを MVVM パターンで作成するのが目的で、C# での基本的なコーディング知識を持っている人が対象です。
目次
MahApps.Metro Ver.2.0.0 リリース
2019/9/23 の .NET Core 3.0 リリースから約 8 か月、α 版を継続リリースしていた MahApps.Metro の .NET Core 対応版となる Ver.2.0.0 が 2020/5/24 にようやく正式リリースされました。以前の正式版(Ver.1.6.5)からほぼ丸 2 年ぶりのリリースは .NET Core 対応だけでなく 298 件の Issue にも対応した大規模リリースです。
※ 2020/6/16 現在は Ver.2.0.1 が最新。
Material Design In XAML Toolkit MahApps.Metro Ver.2.0 対応版リリース
一方、Material Design In XAML Toolkit の .NET Core 対応版は 2019/12 にリリース済みなので、MahApps.Metro Ver.2.0.0 のリリースを待っている状態でしたが、正式リリースに合わせて対応版となる Ver.3.1.3 が 2020/5/25 にリリースされました。
この Ver.3.1.3 は MahApps.Metro と Material Design In XAML Toolkit を統合するための MaterialDesignThemes.MahApps を MahApps.Metro Ver.2 に合わせるのが目的なので、Material Design In XAML Toolkit 本体は Ver.3.1.2 と全く同じだそうです。
このリリースで MahApps.Metro と Material Design In XAML Toolkit の .NET Core 対応については全て完了したと言えるでしょう。
ブログ記事なので細かいバージョンやリリース日まで書きましたが、実際に使用する場合はあまり気にせず基本は最新版をインストールすれば OK です。
.NET Core に対応した MahApps.Metro と Material Design In XAML Toolkit のインストール
MahApps.Metro、Material Design In XAML Toolkit 共に .NET Core 対応に加えていくつかの破壊的変更も行われました。そのため、WPF Prism episode: 19 で紹介した設定から大幅に変わった部分も多いので、このエントリを書くことにしました。
以前(.NET Core 対応前)は Material Design In XAML Toolkit の Wiki『MahApps.Metro integration』 に MahApps.Metro と併せて使用する場合の App.xaml 設定例が載っていましたが、現時点(2021/1 現在)でも情報は古いままなので適用するとエラーになります。
但し、現状(2021/1 現在)では以前(.NET Core 対応前)と同等の見た目になる App.xaml 設定例が Material Design In XAML Toolkit の Issue で提案されているので後程紹介します。
適用するプロジェクトを用意する
まず、MahApps.Metro、Material Design In XAML Toolkit を適用するためのプロジェクトを用意します。
このエントリでは Prism の Blank App(.NET Core)テンプレートから作成したプロジェクトを使用しますが、WPF App(.NET Core)テンプレートから作成した場合でも、既に作成済みのプロジェクトに適用する場合でも設定内容や手順は同じです。
尚、以降紹介する全パッケージの実行には .NET Core 3.1 以上が必要なので未インストールの場合は、先に SDK のインストールを済ましておいてください。
MaterialDesignThemes.MahApps のインストール
まず最初に MahApps.Metro と Material Design In XAML Toolkit を統合するための MaterialDesignThemes.MahApps を Nuget からインストールします。
fig. 2 のように【ソリューションの Nuget パッケージの管理 View】で『material』を検索すると見つかるので、【MaterialDesignThemes.MahApps】をプロジェクトへインストールします。
MahApps.Metro の更新
MaterialDesignThemes.MahApps からインストールされる MahApps.Metro と Material Design In XAML Toolkit は最新版ではないので、まずは fig. 3 のように MahApps.Metro を手動で最新バージョンに更新します。
fig. 3 のように【ソリューションの Nuget パッケージの管理 View】で『mah』を検索すると見つかるので、プロジェクトへインストールします。
MahApps.Metro と Material Design In XAML Toolkit で画面を作成する場合は MahApps.Metro.IconPacks もあると便利なので一緒にインストールしておきます。(MahApps.Metro.IconPacks は必須ではありません)
MahApps.Metro.IconPacks については別途『MahApps.Metro.IconPacks で SVG アイコンを表示する【exhibition #2 WPF UI Gallery】』を書いたので、そちらを読んでください。
Material Design In XAML Toolkit の更新
最後に Material Design In XAML Toolkit も最新版に更新します。
fig. 4 のように【ソリューションの Nuget パッケージの管理 View】で『material』を検索すると見つかるので、プロジェクトへインストールします。
併せて Material Design In XAML Toolkitには MaterialDesignColors も必要なのでインストールします。
fig. 5 のように【ソリューションの Nuget パッケージの管理 View】で『material』を検索すると見つかるので、プロジェクトへインストールします。
以上のパッケージを 5 つインストールしたら準備完了ですが、MahApps.Metro、Material Design In XAML Toolkit、MahApps.Metro.IconPacks の 3 パッケージはそれぞれの GitHub Release ページからデモアプリもダウンロードしておく事をお勧めします。
又、Prism Module のように DLL へ UI 部品を置いているような場合は、DLL のプロジェクトにも同じ手順で 5 パッケージのインストールが必要です。
※ Prism Module への適用は最後辺りに新しく章を追記しています
続いて MetroWindow を設定します。
Window の継承元を MetroWindow に変更
Window を MetroWindow として表示したい場合はプロジェクトに含まれる全 Window に以下の対応を行う必要があります。始めに Window を通常のデザイナで開いて src. 1 のように変更します。
1 2 3 4 5 6 7 8 9 10 11 12 13 | <metro:MetroWindow x:Class="MahAppsNetCore.MainWindow" ↑ <Window x:Class="MahAppsNetCore.Views.MainWindow" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:metro="http://metro.mahapps.com/winfx/xaml/controls" xmlns:prism="http://prismlibrary.com/" prism:ViewModelLocator.AutoWireViewModel="True" Title="{Binding Title}" Height="480" Width="640"> <Grid> </Grid> </metro:MetroWindow> |
src. 1 の 6 行目のように xmlns を追加してから、元の 3 行目を 1 行目に変更します。1 行目を変更すると 13 行目は自動的に変わります。
続いて、*.xaml だけでなく *.xaml.cs にも変更が必要なので Window のコードビハインドを開いて、src. 2 の 8行目の継承元を MetroWindow に変更します。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 | using MahApps.Metro.Controls; namespace MahAppsNetCore { /// <summary> /// Interaction logic for MainWindow.xaml /// </summary> public partial class MainWindow : MetroWindow // WindowをMetroWindowに変更 { public MainWindow() { InitializeComponent(); } } } |
以上の 2 か所を変更すると MetroWindow が表示されるようになります。
ここまでは WPF Prism episode: 19 で紹介した内容と同じですが、次に紹介する App.xaml に追加する内容はかなり変わっているので気を付けてください。
App.xaml に Resource を追加する(2021/1 追記)
前章の先頭にも書いた通り、以前(.NET Core リリース前)は Material Design In XAML Toolkit の Wiki『MahApps.Metro integration』 に MahApps.Metro と Material Design In XAML Toolkit を統合して使用するための App.xaml 例が載っていましたが、それをそのまま使用するとエラーになります。
そのため App.xaml の記述内容があまり理解できていない管理人が試行錯誤して何とか以前(.NET Core リリース前)の見た目に近づけることができたので、このエントリで紹介していましたが、このエントリ公開前に Material Design In XAML Toolkit の Issue #1896 に設定例が提案されていたようです…
Wiki の更新は Watch していましたが、Issue は対象外だったので 2020 年末辺りまで気が付きませんでした… そんな中、ReactiveProperty のメンテナーとしてもお馴染みのかずきさんが書かれた『WPF でマテリアルデザインをするための土台作りの手順 – Qiita』を読んで Issue の存在に気付き、動作確認もできたので、ようやくこのエントリを更新します。
MahApps.Metro と Material Design In XAML Toolkit を統合して使用するための App.xaml
かずきさんの記事 と同じですが、App.xaml へ src. 3 のハイライト部分を追加すれば以前と同じ見た目の MetroWindow が表示されるはずです。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 | <prism:PrismApplication x:Class="MahAppsNetCore.App" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:prism="http://prismlibrary.com/"> <Application.Resources> <ResourceDictionary> <ResourceDictionary.MergedDictionaries> <!-- MahApps --> <ResourceDictionary Source="pack://application:,,,/MahApps.Metro;component/Styles/Controls.xaml"/> <ResourceDictionary Source="pack://application:,,,/MahApps.Metro;component/Styles/Fonts.xaml"/> <ResourceDictionary Source="pack://application:,,,/MahApps.Metro;component/Styles/Themes/Light.Violet.xaml"/> <!-- Material Design --> <ResourceDictionary Source="pack://application:,,,/MaterialDesignThemes.Wpf;component/Themes/MaterialDesignTheme.Light.xaml" /> <ResourceDictionary Source="pack://application:,,,/MaterialDesignThemes.Wpf;component/Themes/MaterialDesignTheme.Defaults.xaml" /> <ResourceDictionary Source="pack://application:,,,/MaterialDesignColors;component/Themes/Recommended/Primary/MaterialDesignColor.DeepPurple.xaml" /> <ResourceDictionary Source="pack://application:,,,/MaterialDesignColors;component/Themes/Recommended/Accent/MaterialDesignColor.Lime.xaml" /> <!-- Material Design: MahApps Compatibility --> <ResourceDictionary Source="pack://application:,,,/MaterialDesignThemes.MahApps;component/Themes/MaterialDesignTheme.MahApps.Fonts.xaml" /> <ResourceDictionary Source="pack://application:,,,/MaterialDesignThemes.MahApps;component/Themes/MaterialDesignTheme.MahApps.Flyout.xaml" /> </ResourceDictionary.MergedDictionaries> <!-- MahApps Brushes --> <SolidColorBrush x:Key="MahApps.Brushes.Highlight" Color="{DynamicResource Primary700}"/> <SolidColorBrush x:Key="MahApps.Brushes.AccentBase" Color="{DynamicResource Primary600}" /> <SolidColorBrush x:Key="MahApps.Brushes.Accent" Color="{DynamicResource Primary500}"/> <SolidColorBrush x:Key="MahApps.Brushes.Accent2" Color="{DynamicResource Primary400}"/> <SolidColorBrush x:Key="MahApps.Brushes.Accent3" Color="{DynamicResource Primary300}"/> <SolidColorBrush x:Key="MahApps.Brushes.Accent4" Color="{DynamicResource Primary200}"/> <SolidColorBrush x:Key="MahApps.Brushes.WindowTitle" Color="{DynamicResource Primary700}"/> <SolidColorBrush x:Key="MahApps.Brushes.Selected.Foreground" Color="{DynamicResource Primary500Foreground}"/> <LinearGradientBrush x:Key="MahApps.Brushes.Progress" EndPoint="0.001,0.5" StartPoint="1.002,0.5"> <GradientStop Color="{DynamicResource Primary700}" Offset="0"/> <GradientStop Color="{DynamicResource Primary300}" Offset="1"/> </LinearGradientBrush> <SolidColorBrush x:Key="MahApps.Brushes.CheckmarkFill" Color="{DynamicResource Primary500}"/> <SolidColorBrush x:Key="MahApps.Brushes.RightArrowFill" Color="{DynamicResource Primary500}"/> <SolidColorBrush x:Key="MahApps.Brushes.IdealForeground" Color="{DynamicResource Primary500Foreground}"/> <SolidColorBrush x:Key="MahApps.Brushes.IdealForegroundDisabled" Color="{DynamicResource Primary500}" Opacity="0.4"/> </ResourceDictionary> </Application.Resources> </prism:PrismApplication> |
fig. 6 は App.xaml を src. 3 にした場合の画面です。
以前に MahApps.Metro や Material Design In XAML Toolkit を使用したことがないと分からないかもしれませんが、MahApps.Metro Ver. 2.0.0 リリース前と同じ見た目で表示されます。
そして、以前公開していた管理人が試行錯誤した App.xaml で表示したのが fig. 7 の画面です。
パッと見、違いが分からないかもしれませんが、fig. 7 はタイトルバーカラーが少し濃くなっています。
Material Design In XAML Toolkit の Issue で提案された App.xaml は管理人もまだあまり触っていないので細かい部分までは分かりませんが、2021 年以降は fig. 6 の App.xaml を採用するつもりなので、何かあればこのエントリを更新したいと思います。
尚、src. 3 の App.xaml は Material Design In XAML Toolkit のデフォルトカラーを指定しているので、変更したい場合は src. 3 の 11 行目、14 行目、16、17 行目の色指定をデモアプリ等を確認しながら変更してください。src. 4 は変更箇所の抜粋です。
1 2 3 4 | <ResourceDictionary Source="pack://application:,,,/MahApps.Metro;component/Styles/Themes/Light.Violet.xaml"/> <ResourceDictionary Source="pack://application:,,,/MaterialDesignThemes.Wpf;component/Themes/MaterialDesignTheme.Light.xaml" /> <ResourceDictionary Source="pack://application:,,,/MaterialDesignColors;component/Themes/Recommended/Primary/MaterialDesignColor.DeepPurple.xaml" /> <ResourceDictionary Source="pack://application:,,,/MaterialDesignColors;component/Themes/Recommended/Accent/MaterialDesignColor.Lime.xaml" /> |
色を変更したい場合、src. 4 の 1行目は MahApps.Metro のカラー指定なので、2 、3 行目と一致させる必要があるので注意してください。又、定義済みカラーはどちらにしかない場合もあるので src. 4 のように近い色(Violet、DeepPurple)を自力で探す場合もあると思います。
そんな訳で今後、App.xaml は Material Design In XAML Toolkit の Issue で提案されていた設定を採用しますが、管理人が試行錯誤した経緯も以下↓にスポイラーで縮めて残しておきます。何かの参考になるとは言えませんが、結構苦労したので時間があれば読んでください。
※ 尚、GitHub リポジトリの App.xaml には halation ghost 独自 Ver. もコメントとして残しています。
※ 以下の『App.xaml に Resource を追加する(halation ghost 独自 Ver.)』をクリックすると残している文章が表示されます。
MahApps.Metro と Material Design In XAML Toolkit を統合する場合の App.xaml についての考察
Material Design In XAML Toolkit の Issue に App.xaml 例が投稿されたのが 2020 年 6 月。担当が割り当てられた後の最後の反応も 2020 年 6 月ですが、Wiki は未だに(2021/1 現在)更新されていません。
コントリビューターに余裕が無いから… とも考えられますが、管理人的には次のメジャーバージョン Ver. 4.0.0 待ちだと予想しています。Issue にピン止めされている『Breaking 4.0.0 changes #1705』にも書かれているように Ver. 4.0.0 以降からブラシ名等を MahApps.Metro のような構造化名に大幅変更予定なので、現状は敢えて対応していないのかも… と勝手に予想しています。
あくまでも管理人の予想なので実際にどうなるかは分かりませんが、何かあれば又記事にしたいと思います。
Prism Module への適用(2020/8/20 追記)
このサイトで紹介しているサンプルは MVVM フレームワークの Prism を使用したものがほとんどです。ここまでは Shell と呼ばれる実行可能プロジェクトに対してのインストールや設定を紹介して来ましたが、Prism には Module と呼ばれるクラスライブラリプロジェクトに置いた UserControl を Window へ動的に表示する機能を持ち、.NET Core WPF Prism MVVM 入門 2020 step: 4 で紹介した通り、入力項目のようなユーザが実際に操作するコントロールは Module の部分 View に配置します。
そのため、Material Design In XAML Toolkit 等のコントロールは Module にも配置する事がほとんどです。そして Module は途中で追加する事も多いので、新規で追加した Prism の Module へ MahApps.Metro と Material Design In XAML Toolkit をインストールする手順も紹介します。
まず、実行可能プロジェクトと同じく fig. 14 のように【ソリューションの Nuget パッケージの管理】を開いて【インストール済み タブ】から新規に追加した Module へインストールします。
fig. 14 のように新規追加した Module に対して以下の 4 パッケージをインストールします。
- MaterialDesignThemes.MahApps
- MaterialDesignThemes
- MaterialDesignColors
- MahApps.Metro
参照タブからインストールしても構いませんが、都度検索する必要も無いので【インストール済み タブ】からインストールする方が楽だと思います。インストールが完了すると Module 側の準備は完了です。
後は、Shell(スタートアッププロジェクト)に Module の参照を追加して一度ビルドかリビルドを通しておけば Module へ MahApps.Metro や Material Design In XAML Toolkit のコントロールが配置できるようになります。別途 ResourceDictionary.xaml 等を追加する必要はありません。
場合によっては MahApps.Metro や Material Design In XAML Toolkit の【Style】等を指定した後に『リソースが見つかりません』的なコンパイルエラーが発生する事もありましたが、何度か実行したり、ソリューションを開きなおしたり、Visual Studio を再起動したり… 等とりあえずしばらくすればコンパイルエラーが消えるので、それまで待つしかないと思います。管理人も確実な解決方法は知りません。
重要なのは【特に何もしない】事です。何か設定等を変更して解消した事はありません。何か分かれば追記しますが、IntelliSence の候補も表示されますし、実行しても問題なく設定した Style のコントロールが表示されるので、とりあえずしばらく待ってみてください。
Prism の Module で MahApps.Metro や Material Design In XAML Toolkit を使用する場合の準備は以上です。
まとめ的なひとこと
MahApps.Metro と Material Design In XAML Toolkit の .NET Core 対応はようやく始まったばかりなので完全統合とはいかず、少し歪な感じの統合ですが今後はテーマの指定方法も集約していく方向に進んでいくと思うので、とりあえずは経過を見守ろうかと思っています。
今回紹介したサンプルもいつも通り GitHub リポジトリ に上げておきます。
※ リポジトリも 2021/1 版の内容に合わせて更新しています
GUIアプリ作成にこちらのサイトを参考にさせてもらってます!MahApps.Metro と Material Design In XAML Toolkitの統合でエラーが出ました…
の2行をコピーした際、
System.Windows.Markup.XamlParseException: ”プロパティ ‘System.Windows.ResourceDictionary.Source’ の Set で例外がスローされました。’
FileNotFoundException: Could not load file or assembly ‘MaterialDesignThemes.MahApps, Culture=neutral, PublicKeyToken=null’. 指定されたファイルが見つかりません
とのことです。他サイトやエラーの原因を探ってみたのですが、全くわかりませんでした。
VS2022 ターゲット .Net 7 です。
もし何か原因をご存知でしたら、教えていただけると嬉しいです。
【Material Design: MahApps Compatibility】のコメント下の2行をコピーした時です。誤字ってました。申し訳有りません。