MahAppsでマテリアルデザインっぽいボタンを実装する

WPFのオープンソースのGUIライブラリMahAppsを使ってマテリアルデザイン風のボタンをサクッと実装してみました。

  • 作成環境
    • Windows10
    • VisualStudio2017 Update3 (15.3.5)
    • .NET Framework 4.7
    • MahApps.Metro使用
    • FLATICONを利用

出来上がったもの

使った小技が以下の通りで、、、

  • MahAppsでウインドウデザインを変更する
  • MahAppsの丸いボタンを使用する
  • MahAppsでウインドウダイアログを表示する
  • ボタンにDropShadowEffectで影をつける

出来上がったアプリの動作は以下の通りです。

プロジェクトにMahAppsを追加

公式のドキュメントに書いてある通りなのですが、まずはVisualStudio上から普通にWPFプロジェクトを作成し、NuGetからMahAppsを導入します。

ソリューションエクスプローラからプロジェクトを右クリックしてコンテキストメニューから[NuGet パッケージの管理]を選択します。

f:id:Takachan:20170921231845p:plain

NuGetのタブが表示されるので、タブ内で[参照]を選択し、"mahapps"と入力してパッケージを探します。

検索結果がリストに表示されるので、MahApps出てきたら選択して右側ペインから[インストール]を選択します。バージョン最新版を選択しておけば間違いないです。

f:id:Takachan:20170921232234p:plain

勝手に出力ウインドウが表示されてインストール状況が表示されます。最後に以下メッセージが出たら成功です。

'MahApps.Metro 1.5.0' が MahMaterial に正常にインストールされました
NuGet の操作の実行に 4.61 sec かかりました
経過した時間: 00:00:06.2140746
========== 終了 ==========

次に、MahAppsのスタイルを使用するためにApp.xmlに以下記述を追加します。

// App.xaml


<Application x:Class="MahMaterial.App"
             xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
             xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
             xmlns:local="clr-namespace:MahMaterial"
             StartupUri="MainWindow.xaml">
    <Application.Resources>
        <!-- ↓↓ 追加 ↓↓ -->
        <ResourceDictionary>
            <ResourceDictionary.MergedDictionaries>
                <!-- MahApps.Metro resource dictionaries. Make sure that all file names are Case Sensitive! -->
                <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" />
                <!-- Accent and AppTheme setting -->
                <ResourceDictionary Source="pack://application:,,,/MahApps.Metro;component/Styles/Accents/Blue.xaml" />
                <ResourceDictionary Source="pack://application:,,,/MahApps.Metro;component/Styles/Accents/BaseLight.xaml" />
            </ResourceDictionary.MergedDictionaries>
        </ResourceDictionary>
        <!-- ↑↑ 追加 ↑↑-->
    </Application.Resources>
</Application>

次に、メインウインドウの見た目をMahAppsに変えるためにMainwindow.xamlを以下の通り変更します。

// MainWindow.xaml

<!-- ↓ Windowから変更する -->
<Controls:MetroWindow x:Class="MahMaterial.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:Controls="clr-namespace:MahApps.Metro.Controls;assembly=MahApps.Metro" ←【追加】
                      xmlns:local="clr-namespace:MahMaterial"
                      mc:Ignorable="d"
                      Title="MainWindow"
                      Height="720"
                      Width="1280">
    <Grid>
        
    </Grid>
</Controls:MetroWindow>

このままだとコンパイルエラーが出るため、MainWindow.xaml.csも一緒に変更します。

using MahApps.Metro.Controls; // 追加

namespace MahMaterial
{
    /// <summary>
    /// MainWindow.xaml の相互作用ロジック
    /// </summary>
    //public partial class MainWindow : Window
    public partial class MainWindow : MetroWindow // 基底クラスを変更
    {

これで準備は完了です。

丸いボタンを追加する

MahAppsに標準で丸ボタンがあるのでそれの見た目をカスタマイズします。

よくあるマテリアル風の上下2色のセパレートに丸いボタンをイイ感じに配置してボタンに影を付けます。

<!-- Controls:MetroWindow要素の中身 -->
<Grid>
    <Grid.RowDefinitions>
        <RowDefinition Height="1*"/>
        <RowDefinition Height="1*"/>
    </Grid.RowDefinitions>

    <StackPanel Background="#3746AC"/>
    <StackPanel Grid.Row="1">

        <!-- Styleで丸いボタンを指定する -->
        <Button Margin="0 -23 0 0"
                Width="46"
                Height="46"
                Background="#2196F3"
                BorderThickness="0"
                Style="{DynamicResource MahApps.Metro.Styles.MetroCircleButtonStyle}">
            <Button.Effect>

                <!-- ボタンに影をつける -->
                <DropShadowEffect Color="Black"
                                  Opacity="0.2"
                                  ShadowDepth="5"
                                  Direction="270"/>
            </Button.Effect>
            <Image Width="24" Source="/Assets/plus.png"/>
        </Button>
    </StackPanel>
</Grid>

実行すると以下のような表示になります。

ボタンを押すとエフェクトがかかって少しいい感じです。

f:id:Takachan:20170921235712p:plain

コード全体

作成したコードの全体をGitHubにアップしました。

github.com

以上です。