すでにあるWPFアプリをマテリアルデザインにする

＜2018年一人アドベントカレンダー9日目＞
#はじめに
何番煎じかという内容です。
[こちら](http://neue.cc/2015/09/10_515.html)を参考に自分で手を動かしてみたことの備忘録です。

さて、いつもと違うデザインでアプリを作ってみると、とても新鮮に感じられてテンションが上ります。

Nugetで`MaterialDesignTheme`と`MahApps.Metro`というパッケージをインストールすることで、簡単に見た目をマテリアルデザインにすることができます。

#環境

- Visual Studio 2017


#MaterialDesignTheme
まずはWPFプロジェクトを新規作成するか、すでに作成済みWPFプロジェクトをVisual Studioで開きます。


## インストール
次に、Nugetで`MaterialDesignTheme`を検索してインストールします。
![image.png](https://qiita-image-store.s3.amazonaws.com/0/245438/65b5d0e5-b178-271d-3291-1cf19de8d682.png)


## 設定

`App.xaml`の`ResourceDictionary`に以下のようにコードを入れます。

```xml
    <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
<img src="https://qiita-image-store.s3.amazonaws.com/0/245438/fa98d600-0c73-e4b1-a3a6-37bfcb6ec245.png" title="" alt="image.png" width="60%" height="" >
<img src="https://qiita-image-store.s3.amazonaws.com/0/245438/c16b410b-932d-679f-ef9d-0d81a2e1012d.png" title="" alt="image.png" width="60%" height="" >

### after
<img src="https://qiita-image-store.s3.amazonaws.com/0/245438/a498eeec-7a7f-70e2-9da0-07c87c21b1dd.png" title="" alt="image.png" width="60%" height="" >

<img src="https://qiita-image-store.s3.amazonaws.com/0/245438/ee787758-0a47-cea6-e8c5-dd9654f46476.png" title="" alt="image.png" width="60%" height="" >


となります。

おお、、、？という感じになったのではないでしょうか。
ボタンやプログレスバーの色、形状がマテリアルデザインぽくなってはいますが、UIのデザイン変更にともなってボタンのラベルが収まらなかったり、ラジオボタンが他のコントロールに隠れて切れたりしています。
これは要素ごとにスタイルを設定するなどして調整します。これはいつもどおりです。

それと、一番気になるのがタイトルバーのミスマッチです。タイトルバーだけノーマルなので浮きまくりです。

これを解決するのが`MahApps.Metro`です。
`MahApps.Metro`自体は名前のとおりWPFアプリのWindowのデザインをWindowsのモダンUI風にしてくれるものですが、マテリアルデザインとの相性が良いのです。

# MahApps.Metro

## インストール
Nugetで`MahApps.Metro`を検索してインストールします。
<img src="https://qiita-image-store.s3.amazonaws.com/0/245438/dfe61c86-23ae-da75-a273-a944a529ffb7.png" title="" alt="image.png" width="60%" height="" >


## 設定
xamlファイルの`Window`要素を以下のように変更します。
Window要素の代わりにMahAppsのMetroWindow要素を使います。

```xml
<Window x:Class="MyApplication.MainWindow"
               省略
```

```xml
<mahApps:MetroWindow x:Class="MyApplication.MainWindow"
               省略
        xmlns:mahApps="clr-namespace:MahApps.Metro.Controls;assembly=MahApps.Metro"
```

XML側のWindow要素をMetroWindow要素に変更したので、それに合わせてコードビハインド（xaml.cs）も以下のようにWindowからMetroWindowを継承するように変更します。

```csharp
    public partial class MainWindow : Window
    {
          省略
    }
```

```csharp
    public partial class MainWindow : MahApps.Metro.Controls.MetroWindow
    {
          省略
    }
```

ここはWindowごとに設定する必要があります。

次に、`App.xaml`に`MetroDesignTheme`と同じようにResourceDictionaryに以下のように追記します。
MahApps.Metroのための追記を行った後はいかのようになります。

```xml
    <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>
```

さて、これでどうでしょうか。
一度実行してみましょう。

<img src="https://qiita-image-store.s3.amazonaws.com/0/245438/224ed81d-08ea-6833-e2cc-67c46be717d8.png" title="" alt="image.png" width="60%" height="" >

タイトルバーとステータスバーのデザインが変わり、色はともかくとしてぐっとマテリアルデザインぽくなりました。
さて、`App.xaml`にさらに追記して以下のようにします。

```xml
    <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>
```

ここまでやると、こんな感じになりタイトルバーとステータスバーのデザインはマテリアルデザインっぽくなりました。

<img src="https://qiita-image-store.s3.amazonaws.com/0/245438/4c449422-294c-9ee4-fe13-495d734d6a23.png" title="" alt="image.png" width="60%" height="" >

<img src="https://qiita-image-store.s3.amazonaws.com/0/245438/ebc87bdb-f404-abe9-10a1-ae2f1a382e08.png" title="" alt="image.png" width="60%" height="" >


でも別の問題がでています。
ボタンのデザインがマテリアルデザインじゃなくなっています。
これはスタイルの適用順序のせいです。

上で示した`App.xaml`の例では`MaterialDesignThemes`、`MahApps.Metro`の順に書いていました。このため、`MahApps.Metro`のスタイルが適用されてボタンなどのデザインがマテリアルデザインではなくなってしまっていました。
ということ順番を入れ替えて以下のようにします。

```xml
            <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>
```

そうすると・・・

<img src="https://qiita-image-store.s3.amazonaws.com/0/245438/86d4fbed-1d4d-9d29-69f4-e0a8b81bc7c8.png" title="" alt="image.png" width="60%" height="" >

<img src="https://qiita-image-store.s3.amazonaws.com/0/245438/979e0a02-d763-e3dc-00b1-7731f88b4aa7.png" title="" alt="image.png" width="60%" height="" >


あとはボタンのラベルや、UIの高さなど細々したところを調整します。

<img src="https://qiita-image-store.s3.amazonaws.com/0/245438/2e5117cd-2556-47f1-0133-f9694c05a3e8.png" title="" alt="image.png" width="60%" height="" >


<img src="https://qiita-image-store.s3.amazonaws.com/0/245438/7b4cc142-7b68-308e-4838-d70ce6c7fe81.png" title="" alt="image.png" width="60%" height="" >


# おわりに
いつも見慣れたWPFアプリもこうして見た目を変えるだけで印象がかなり違ってきますし、作るときのモチベーションも上がりますよね。