<2018年一人アドベントカレンダー9日目>
#はじめに
何番煎じかという内容です。
こちらを参考に自分で手を動かしてみたことの備忘録です。
さて、いつもと違うデザインでアプリを作ってみると、とても新鮮に感じられてテンションが上ります。
NugetでMaterialDesignTheme
とMahApps.Metro
というパッケージをインストールすることで、簡単に見た目をマテリアルデザインにすることができます。
#環境
- Visual Studio 2017
#MaterialDesignTheme
まずはWPFプロジェクトを新規作成するか、すでに作成済みWPFプロジェクトをVisual Studioで開きます。
インストール
次に、NugetでMaterialDesignTheme
を検索してインストールします。
設定
App.xaml
のResourceDictionary
に以下のようにコードを入れます。
<Application.Resources>
<ResourceDictionary>
<ResourceDictionary.MergedDictionaries>
<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" />
</ResourceDictionary.MergedDictionaries>
</ResourceDictionary>
</Application.Resources>
とりあえずこれでマテリアルデザインが適用されて、
before
after
となります。
おお、、、?という感じになったのではないでしょうか。
ボタンやプログレスバーの色、形状がマテリアルデザインぽくなってはいますが、UIのデザイン変更にともなってボタンのラベルが収まらなかったり、ラジオボタンが他のコントロールに隠れて切れたりしています。
これは要素ごとにスタイルを設定するなどして調整します。これはいつもどおりです。
それと、一番気になるのがタイトルバーのミスマッチです。タイトルバーだけノーマルなので浮きまくりです。
これを解決するのがMahApps.Metro
です。
MahApps.Metro
自体は名前のとおりWPFアプリのWindowのデザインをWindowsのモダンUI風にしてくれるものですが、マテリアルデザインとの相性が良いのです。
MahApps.Metro
インストール
NugetでMahApps.Metro
を検索してインストールします。
設定
xamlファイルのWindow
要素を以下のように変更します。
Window要素の代わりにMahAppsのMetroWindow要素を使います。
<Window x:Class="MyApplication.MainWindow"
省略
<mahApps:MetroWindow x:Class="MyApplication.MainWindow"
省略
xmlns:mahApps="clr-namespace:MahApps.Metro.Controls;assembly=MahApps.Metro"
XML側のWindow要素をMetroWindow要素に変更したので、それに合わせてコードビハインド(xaml.cs)も以下のようにWindowからMetroWindowを継承するように変更します。
public partial class MainWindow : Window
{
省略
}
public partial class MainWindow : MahApps.Metro.Controls.MetroWindow
{
省略
}
ここはWindowごとに設定する必要があります。
次に、App.xaml
にMetroDesignTheme
と同じようにResourceDictionaryに以下のように追記します。
MahApps.Metroのための追記を行った後はいかのようになります。
<Application.Resources>
<ResourceDictionary>
<ResourceDictionary.MergedDictionaries>
<!--MaterialDesignThemes-->
<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" />
<!--MahApps.Metro-->
<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/Colors.xaml" />
<ResourceDictionary Source="pack://application:,,,/MahApps.Metro;component/Styles/Accents/BaseLight.xaml" />
</ResourceDictionary.MergedDictionaries>
</ResourceDictionary>
</Application.Resources>
さて、これでどうでしょうか。
一度実行してみましょう。
タイトルバーとステータスバーのデザインが変わり、色はともかくとしてぐっとマテリアルデザインぽくなりました。
さて、App.xaml
にさらに追記して以下のようにします。
<Application.Resources>
<ResourceDictionary>
<ResourceDictionary.MergedDictionaries>
<!--MaterialDesignThemes-->
<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" />
<!--MahApps.Metro-->
<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/Colors.xaml" />
<ResourceDictionary Source="pack://application:,,,/MahApps.Metro;component/Styles/Accents/BaseLight.xaml" />
</ResourceDictionary.MergedDictionaries>
<!--MahApps.Metro-->
<SolidColorBrush x:Key="HighlightBrush" Color="{DynamicResource Primary700}"/>
<SolidColorBrush x:Key="AccentColorBrush" Color="{DynamicResource Primary500}"/>
<SolidColorBrush x:Key="AccentColorBrush2" Color="{DynamicResource Primary400}"/>
<SolidColorBrush x:Key="AccentColorBrush3" Color="{DynamicResource Primary300}"/>
<SolidColorBrush x:Key="AccentColorBrush4" Color="{DynamicResource Primary200}"/>
<SolidColorBrush x:Key="WindowTitleColorBrush" Color="{DynamicResource Primary700}"/>
<SolidColorBrush x:Key="AccentSelectedColorBrush" Color="{DynamicResource Primary500Foreground}"/>
<LinearGradientBrush x:Key="ProgressBrush" 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="CheckmarkFill" Color="{DynamicResource Primary500}"/>
<SolidColorBrush x:Key="RightArrowFill" Color="{DynamicResource Primary500}"/>
<SolidColorBrush x:Key="IdealForegroundColorBrush" Color="{DynamicResource Primary500Foreground}"/>
<SolidColorBrush x:Key="IdealForegroundDisabledBrush" Color="{DynamicResource Primary500}" Opacity="0.4"/>
</ResourceDictionary>
</Application.Resources>
ここまでやると、こんな感じになりタイトルバーとステータスバーのデザインはマテリアルデザインっぽくなりました。
でも別の問題がでています。
ボタンのデザインがマテリアルデザインじゃなくなっています。
これはスタイルの適用順序のせいです。
上で示したApp.xaml
の例ではMaterialDesignThemes
、MahApps.Metro
の順に書いていました。このため、MahApps.Metro
のスタイルが適用されてボタンなどのデザインがマテリアルデザインではなくなってしまっていました。
ということ順番を入れ替えて以下のようにします。
<ResourceDictionary.MergedDictionaries>
<!--MahApps.Metro-->
<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/Colors.xaml" />
<ResourceDictionary Source="pack://application:,,,/MahApps.Metro;component/Styles/Accents/BaseLight.xaml" />
<!--MaterialDesignThemes-->
<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" />
</ResourceDictionary.MergedDictionaries>
そうすると・・・
あとはボタンのラベルや、UIの高さなど細々したところを調整します。
おわりに
いつも見慣れたWPFアプリもこうして見た目を変えるだけで印象がかなり違ってきますし、作るときのモチベーションも上がりますよね。